从自然语言到 C++ 表达式

lim*_*ade 9 c++ logic

任务:

将以下自然语言表达式转换为 C++ 表达式。假设所有变量都是非负数或布尔值(值为真或假)。

自然语言:

a 和 b 都为假或 c 为真,但不能同时为真。

我的解决方案:

(a==0 && b==0)xor(c==1)
Run Code Online (Sandbox Code Playgroud)

教授解决方案:

(!a && !b) != c
Run Code Online (Sandbox Code Playgroud)

问题:

  1. 我想我稍微理解了第一个括号,通过说“not-a”和“not-b”,我认为 a 和 b 一定是错误的,前提是 ab 在开始时被假定为非零。对?

  2. 但是说“不等于c”的部分呢?

  3. 我不明白教授的解决方案,谁能帮我分解一下?

感谢您的帮助!

Yur*_*nko 5

我会假设ab并且cbool

让我们画一些真值表:

| a | !a | a==1 | a==0 |
| 0 |  1 |   0  |   1  |
| 1 |  0 |   1  |   0  |
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,aanda==1是等价的,and !aanda==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   |
Run Code Online (Sandbox Code Playgroud)

Soa!=b等价于a xor b,所以我们可以重写(!a && !b) xor c(!a && !b)!=c。如您所见,您的解决方案完全等效,只是用不同的“符号”编写。


UPD:忘记提及了。教授的解决方案看起来完全那样是有原因的。

教授的解决方案更加地道。虽然您的解决方案在技术上是正确的,但它不是惯用的 C++ 代码。

第一个小问题是类型的使用。您的解决方案依赖之间的转换intbool比较时,布尔值,数字或使用xor,这是作用于“按位异或”操作int太迟了。在现代 C++ 中,使用正确类型的值而不是依赖于这种转换,因为它们有时不是那么清楚和难以推理,这是更受欢迎的。对于bool这些值分别是truefalse而不是10。也!=xor因为虽然技术上bools 存储为数字更合适,但从语义上讲,您没有任何数字,只有逻辑值。

第二个问题也是关于成语的。它就在这里:a == 0。将布尔表达式与布尔常量进行比较不是一个好习惯。正如您已经知道的那样,a == true完全等同于 just a,并且a == false是 just !aor not a(我更喜欢后者)。要了解这种比较不好的原因,只需比较两个代码片段并做出决定,就更清楚了:

if (str.empty() == false) { ... }
Run Code Online (Sandbox Code Playgroud)

对比

if (not str.empty()) { ... }
Run Code Online (Sandbox Code Playgroud)