자연어에서 C ++ 표현까지


9

할당:

다음 자연 언어 표현식을 C ++ 표현식으로 변환하십시오. 모든 변수가 음수가 아닌 숫자 또는 부울 (참 또는 거짓 값)이라고 가정하십시오.

자연어 :

a와 b는 모두 false이거나 c는 true이지만 둘다는 아닙니다.

내 해결책 :

(a==0 && b==0)xor(c==1)

교수 솔루션 :

(!a && !b) != c

질문 :

  1. 나는 "not-a"와 "not-b"라고 말함으로써 첫 번째 대괄호를 약간 이해한다고 생각합니다. 나는 ab가 처음에 0이 아닌 것으로 가정한다면 a와 b는 틀렸다고 생각합니다. 권리?

  2. 그러나 "c와 같지 않다"는 부분은 어떻습니까?

  3. 교수 솔루션을 이해하지 못합니다. 누군가 나를 위해 분해 할 수 있습니까?

도움을 주셔서 감사합니다!


일반적으로 음성 언어 부울 식을 코드로 변환하는 데주의해야합니다. 일반적인 실수는 a == b or c대신 "A는 B 또는 C와 같음"을 번역하는 것입니다 a == b or a ==c. 음성 lanuage가 부정확 실제로 모두 해석이 유효 할 수 있다는 문제는
idclev 463,035,818

답변:


5

나는 그것을 가정합니다 a, b하고 c있습니다 bool.

진리표를 그리자 :

| a | !a | a==1 | a==0 |
| 0 |  1 |   0  |   1  |
| 1 |  0 |   1  |   0  |

보시다시피, a그리고 a==1동등 !a하고 a==0또한 동일하므로 다시 (a==0 && b==0)xor(c==1)로 쓸 수 있습니다 (!a && !b) xor c.

이제 더 많은 진리표 :

| a | b | a xor b | a != b |
| 0 | 0 |    0    |    0   |
| 0 | 1 |    1    |    1   |
| 1 | 0 |    1    |    1   |
| 1 | 1 |    0    |    0   |

따라서 a!=b와 동일 a xor b하므로 다시 쓸 (!a && !b) xor c(!a && !b)!=c있습니다. 보시다시피, 귀하의 솔루션은 완전히 '동등한'기호로 작성되었습니다.


UPD : 언급을 잊었습니다. 교수의 솔루션이 그렇게 정확하게 보이는 이유가 있습니다.

교수의 해결책은 더 관용적입니다. 솔루션은 기술적으로 정확하지만 관용적 인 C ++ 코드는 아닙니다.

첫 번째 작은 문제는 유형 사용입니다. 귀하의 솔루션은 부울 값을 숫자와 비교하거나을 사용 하는``bit-wise exclusive 또는 ''연산자 인 을 변환 할 때 int와 변환 사이에 의존합니다 . 현대 C ++에서는 올바른 유형의 값을 사용하고 때로는 너무 명확하지 않고 추론하기 어려운 변환에 의존하지 않는 것이 훨씬 좋습니다. 들면 등 값인 과 대신 과 각각. 또한 기술적 으로 숫자로 저장 되기는하지만, 의미 적으로 논리 값만있는 숫자는 없기 때문에 보다 적합 합니다.boolxorintbooltruefalse10!=xorbool

두 번째 문제는 관용구에 관한 것입니다. 여기 있습니다 : a == 0. 부울 표현식을 부울 상수와 비교하는 것은 좋은 방법으로 간주되지 않습니다. 당신이 이미 알고 있듯이, a == truejust a와 완전히 동일하며 a == false단지 !a또는 not a(나는 후자를 선호합니다). 비교가 좋지 않은 이유를 이해하려면 두 개의 코드 스 니펫을 비교하고 결정하십시오.

if (str.empty() == false) { ... }

vs

if (not str.empty()) { ... }

1
이 답변은 기술적으로는 정확하지만이 연습의 요점 인 유형과 관용적 C ++에 대해서는 언급하지 않아도됩니다.
Konrad Rudolph

@KonradRudolph, 그래, 나는 그것을 언급하는 것을 완전히 잊었다. 어쩌면 나는 대답을 편집 할 것입니다
Yuri Kovalenko

3

비트가 아닌 부울 생각

요약하면, 교수의 솔루션은 비트 연산자 대신 부울 연산자를 사용하고 부울을 정수로 취급하기 때문에 더 좋습니다 (그러나 여전히 틀리고 엄격하게 말하면 아래를 참조하십시오). 표현은 c==1"C에 해당하는"C는 (명시된 할당에 따라) 다수 일 수도이라면 (C)의 0이 아닌 값을 나타내는 것으로 간주하기 때문에 부정확 나타내는 true.

안전한 경우에도 부울을 0 또는 1과 비교하지 않는 것이 좋은 이유에 대해서는 이 질문 을 참조하십시오 .

사용하지 않는 한 가지 좋은 이유 xor는 이것이 비트 단위 배타적이거나 연산 이기 때문 입니다. 왼쪽과 오른쪽이 모두 1 또는 0으로 변환되는 부울 표현식이기 때문에 예제에서 작동합니다 (다시 1 참조 ).

부울 배타적이거나 실제로 !=입니다.

표현 세분화

교수의 솔루션을 더 잘 이해하려면 부울 연산자를 "대체 토큰"으로 대체하는 것이 가장 쉽고, 이는 더 나은 redable (imho) 및 완전히 동등한 C ++ 코드로 바뀝니다. 'not'for '!' 그리고 '&&'에 대한 'and'

    (not a and not b) != c

불행히도 exclusive_or이외의 논리 연산자 not_eq는 없습니다.이 경우에는 도움이되지 않습니다.

자연어 표현을 세분화하면 :

a와 b는 모두 false이거나 c는 true이지만 둘다는 아닙니다.

부울 제안 A와 B에 대한 문장으로 먼저 :

A 또는 B이지만 둘다는 아닙니다.

이것은 A != B(A 및 B 유형이 아닌 부울에만 해당) 으로 변환됩니다 .

그런 다음 제안 A는

a와 b는 모두 거짓이다

이것은 다음과 같이 말할 수 있습니다

a는 거짓이고 b는 거짓

로 변환되고 (not a and not b)마지막으로

c는 사실이다

간단히로 번역됩니다 c. 그들을 결합하면 다시 얻을 수 있습니다 (not a and not b) != c.

이 표현이 어떻게 작동하는지에 대한 자세한 설명을 위해, 나는 다른 사람들이 그들의 대답에 제시 한 진리표를 참조합니다.

둘 다 틀렸어

그리고 내가 nitpick 할 수 있다면 : 원래 과제는 a, b 및 c가 음수가 아닌 수라고 명시했지만 숫자라면 숫자 0과 1로 제한되어야한다고 분명하게 언급하지 않았습니다. true관습 적으로 0 이 아닌를 나타내는 경우 다음 코드는 놀라운 대답을 산출합니다 .

    auto c = 2; // "true" in some way
    auto a = 0; // "false"
    auto b = 0; // "false"

    std::cout << ((!a && !b) != c);

// this will output: 1 (!)
// fix by making sure that != compares booleans:

    std::cout << ((!a && !b) != (bool)c);


잘 만하면 a, b그리고 c로 선언되어 bool있는 경우가 c == 1있습니다 올바른 흉포 코드 불구하고. 어쨌든 이것은 내가 작성한 답변입니다. OP의 코드는 교수의 코드와 같을 수 있지만 C ++은 나쁩니다.
Konrad Rudolph

1
OP의 과제 텍스트에서 @KonradRudolph : variables are non-negative numbers or boolean. 그래서 대부분의 다른 사람들이 놓친 세부 사항 (처음에는 나를 포함하여)을 잡으려고 나에게 @dhavenith에게 +1.
Frodyne

좋아요 감사합니다! 그러나 내가 이해하지 못하기 때문에 교수님의 해결책을 설명해 주시겠습니까?
리모 네이드

교수님의 솔루션에 대한 대체 철자를 추가했습니다. 이것은 표현을 명확하게하는 데 도움이됩니다. 더 자세한 설명은 @YuriKovalenko의 답변에있는 진리표가 표현에 접근하는 가장 좋은 방법이라고 생각합니다.
dhavenith

2

나는 더 많은 단어로 설명하려고 노력할 것이다 : 숫자는 암시 적으로 부울 값으로 변환 될 수있다 :

정수 0, 부동 소수점 및 범위가없는 열거의 경우 값 0과 널 포인터 및 널 포인터 대 멤버 값은 false가됩니다. 다른 모든 값은 적용됩니다.

cppreference의 소스

이것은 다음과 같은 결론으로 ​​이어집니다.

  • a == 0는 부울로 변환 된 후 반전 !a되기 때문에 a와 동일 !(a != 0)합니다. b도 마찬가지입니다.

  • c==1경우에만 진정한 될 것 c 같습니다 변환을 사용하여 1을 (bool)c산출 할 truec != 0뿐만 아니라 경우 c == 1. 따라서 일반적으로 1을 사용 하여을 나타내는 값을 사용 하지만 작동하지 않기 때문에 작동 할 수 있습니다true .

  • a != ba xor bwhen abar 부울 표현식 과 동일 합니다. 하나의 값 또는 다른 값이 true 일 때 둘 다 해당되는 것은 아닙니다. 이 경우, 왼쪽은 (a==0 && b==0)오른쪽이되도록, 부울이다 c도 따라서 양쪽 부울 식으로 해석되어 논리 값으로 변환되고, 따라서, !=동일하다 xor,이 경우이다.

다른 답변이 제공 한 진실 표로이 모든 것을 직접 확인할 수 있습니다.


2

진리표에서 볼 수 있듯이 :

  • !( not)와 ==0동일한 결과를 제공합니다.
  • !=xor동일한 결과를 제공합니다.
  • c==1 그냥 같은 c

따라서 하나는 다른 아래에서이 두 표현식이 같은 결과를주는 이유를 보여줍니다.

(a==0 && b==0) xor (c==1)
(!a   && !b)   !=   c

진리표 :

아니

    |   | ! |
    | 0 | 1 |
    | 1 | 0 |

== 0

    |   |==0|
    | 0 | 1 |
    | 1 | 0 |

== 1

    |   |==1|
    | 0 | 0 |
    | 1 | 1 |

   | a | b | && |
   | 0 | 0 |  0 |
   | 0 | 1 |  0 |
   | 1 | 0 |  0 |
   | 1 | 1 |  1 |

같지 않다

   | a | b | != |
   | 0 | 0 |  0 |
   | 0 | 1 |  1 |
   | 1 | 0 |  1 |
   | 1 | 1 |  0 |

XOR

   | a | b |xor|
   | 0 | 0 | 0 |
   | 0 | 1 | 1 |
   | 1 | 0 | 1 |
   | 1 | 1 | 0 |
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.