[英]From natural language to C++ expression
Translate the following natural language expressions to C++ expressions.
将以下自然语言表达式转换为 C++ 表达式。 Assume that all the variables are non-negative numbers or boolean (of value true or false).
假设所有变量都是非负数或布尔值(值为真或假)。
Either a and b are both false or c is true, but not both.
a 和 b 都为假或 c 为真,但不能同时为真。
(a==0 && b==0)xor(c==1)
(!a && !b) != c
I think I slightly understand the first bracket, by saying "not-a" and "not-b" I think that a and b must then be wrong, provided ab are assumed to be non-zero in the beginning.我想我稍微理解了第一个括号,通过说“not-a”和“not-b”,我认为 a 和 b 一定是错误的,前提是 ab 在开始时被假定为非零。 Right?
对?
But what about the part that says "unequal to c"?但是说“不等于c”的部分呢?
I don't understand the Professors solution, can anyone break it down for me?我不明白教授的解决方案,谁能帮我分解一下?
Thank you for the help!感谢您的帮助!
I'll assume that a
, b
and c
are bool
.我假设
a
, b
和c
是bool
。
Let's draw some truth tables:让我们画一些真值表:
| a | !a | a==1 | a==0 |
| 0 | 1 | 0 | 1 |
| 1 | 0 | 1 | 0 |
As you can see, a
and a==1
are equivalent, and !a
and a==0
are also equivalent, so we can rewrite (a==0 && b==0)xor(c==1)
as (!a && !b) xor c
.可以看到,
a
和a==1
是等价的, !a
和a==0
也是等价的,所以我们可以将(a==0 && b==0)xor(c==1)
改写为(!a && !b) xor c
。
Now some more truth tables:现在还有一些真值表:
| a | b | a xor b | a != b |
| 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 1 | 1 |
| 1 | 1 | 0 | 0 |
So a!=b
is equivalent to a xor b
, so we can rewrite (!a && !b) xor c
to (!a && !b)!=c
.所以
a!=b
等价于a xor b
,所以我们可以将(!a && !b) xor c
重写为(!a && !b)!=c
。 As you see, your solutions are fully equivalent, just written with different 'signs'.如您所见,您的解决方案完全等效,只是用不同的“符号”编写。
UPD : Forgot to mention. UPD :忘记提及了。 There are reasons why professor's solution looks exactly in that way.
教授的解决方案看起来完全那样是有原因的。
The professor's solution is more idiomatic.教授的解决方案更加地道。 While your solution is technically correct, it's not an idiomatic C++ code.
虽然您的解决方案在技术上是正确的,但它不是惯用的 C++ 代码。
First little issue is usage of types.第一个小问题是类型的使用。 Your solution relies on conversion between
int
and bool
when you compare boolean value to a number or use xor
, which is a 'bit-wise exclusive or' operator acting on int
s too.当您将布尔值与数字进行比较或使用
xor
,您的解决方案依赖于int
和bool
之间的转换, xor
也是作用于int
的“按位异或”运算符。 In a modern C++ it is much more appreciated to use values of correct types and not to rely on such conversions as they're sometimes not so clear and hard to reason about.在现代 C++ 中,使用正确类型的值而不是依赖于这种转换,因为它们有时不是那么清楚和难以推理,这是更受欢迎的。 For
bool
such values are true
and false
instead of 1
and 0
respectively.对于
bool
这些值分别为true
和false
而不是1
和0
。 Also !=
is more appropriate than xor
because while technically bool
s are stored as numbers, but sematically you haven't any numbers, just logical values.此外
!=
比xor
更合适,因为虽然技术上bool
s 存储为数字,但从语义上讲,您没有任何数字,只有逻辑值。
Second issue is about idiomacy too.第二个问题也是关于成语的。 It lies here:
a == 0
.它就在这里:
a == 0
。 It is not considered a good practice to compare boolean expressions to boolean constants.将布尔表达式与布尔常量进行比较不是一个好习惯。 As you already know,
a == true
is fully equivalent to just a
, and a == false
is just !a
or not a
(I prefer the latter).正如您已经知道的那样,
a == true
完全等同于a
,而a == false
只是!a
或not a
(我更喜欢后者)。 To understand the reason why that comparing isn't good just compare two code snippets and decide, which is clearer:要了解这种比较不好的原因,只需比较两个代码片段并做出决定,就更清楚了:
if (str.empty() == false) { ... }
vs对比
if (not str.empty()) { ... }
In summary, your professor's solution is better (but still wrong, strictly speaking, see further down) because it uses boolean operators instead of bitwise operators and treating booleans as integers.总而言之,您教授的解决方案更好(但严格来说仍然是错误的,请往下看),因为它使用布尔运算符而不是按位运算符并将布尔值视为整数。 The expression
c==1
to represent "c is true" is incorrect because if c may be a number (according to the stated assignment) then any non-zero value of c is to be regarded as representing true
.表示“c 为真”的表达式
c==1
是不正确的,因为如果 c 可能是一个数字(根据规定的赋值),那么 c 的任何非零值都将被视为表示true
。
See this question on why it's better not to compare booleans with 0 or 1, even when it's safe to do so.请参阅此问题,了解为什么最好不要将布尔值与 0 或 1 进行比较,即使这样做是安全的。
One very good reason not to use xor
is that this is the bit-wise exclusive or operation.不使用
xor
一个很好的理由是,这是按位异或运算。 It happens to work in your example because both the left hand side and right hand side are boolean expressions that convert to 1 or 0 (see again 1 ).它恰好适用于您的示例,因为左侧和右侧都是转换为 1 或 0 的布尔表达式(再次参见1 )。
The boolean exclusive-or is in fact !=
.布尔异或实际上是
!=
。
To understand your professor's solution better, it's easiest to replace the boolean operators with their "alternative token" equivalents, which turns it into better redable (imho) and completely equivalent C++ code: Using 'not' for '!'为了更好地理解教授的解决方案,最简单的方法是将布尔运算符替换为它们的“替代标记”等价物,这将其变成更好的 redable (imho) 和完全等效的 C++ 代码:使用 'not' for '!' and 'and' for '&&' you get
和 'and' 为 '&&' 你得到
(not a and not b) != c
Unfortunately, there is no logical exclusive_or
operator other than not_eq
, which isn't helpful in this case.不幸的是,除了
not_eq
之外没有逻辑上的exclusive_or
运算符,这在这种情况下没有帮助。
If we break down the natural language expression:如果我们分解自然语言表达式:
Either a and b are both false or c is true, but not both.
a 和 b 都为假或 c 为真,但不能同时为真。
first into a sentence about boolean propositions A and B:首先进入关于布尔命题 A 和 B 的句子:
Either A or B, but not both.
A 或 B,但不能两者兼而有之。
this translates into A != B
(only for booleans, not for any type A and B).这转化为
A != B
(仅适用于布尔值,不适用于任何类型 A 和 B)。
Then proposition A was那么命题 A 是
a and b are both false
a 和 b 都是假的
which can be stated as可以表示为
a is false and b is false
a 是假的,b 是假的
which translates into (not a and not b)
, and finally转化为
(not a and not b)
,最后
c is true
c 是真的
Which simply translates into c
.这简单地转换为
c
。 Combining them you get again (not a and not b) != c
.将它们结合起来,你又得到了
(not a and not b) != c
。
For further explanation how this expression then works, I defer to the truth tables that others have given in their answers.为了进一步解释这个表达式是如何工作的,我遵循其他人在他们的答案中给出的真值表。
And if I may nitpick: The original assignment stated that a, b and c can be non-negative numbers, but did not unambiguously state that if they were numbers, they should be limited to the values 0 and 1. If any number that is not 0 represents true
, as is customary, then the following code would yield a surprising answer :如果我可以吹毛求疵:最初的分配说明 a、b 和 c 可以是非负数,但没有明确说明如果它们是数字,它们应该限制为值 0 和 1。如果任何数字是不是 0 代表
true
,按照惯例,那么下面的代码会产生一个令人惊讶的答案:
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);
As we can see from the truth tables:正如我们从真值表中看到的:
!
( not
) and ==0
give the same results. not
) 和==0
给出相同的结果。!=
and xor
give the same results. !=
和xor
给出相同的结果。c==1
is the same as just c
c==1
和c
So one under the other, shows why these 2 expressions give the same result:所以一个在另一个下面,说明为什么这两个表达式给出相同的结果:
(a==0 && b==0) xor (c==1)
(!a && !b) != c
Truth tables :真值表:
Not不是
| | ! |
| 0 | 1 |
| 1 | 0 |
==0 ==0
| |==0|
| 0 | 1 |
| 1 | 0 |
==1 ==1
| |==1|
| 0 | 0 |
| 1 | 1 |
And和
| a | b | && |
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
Not equal不相等
| 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 |
I will tryto explain with some more words: Numbers can be implicitly converted to boolean values:我将尝试用更多的话来解释:数字可以隐式转换为布尔值:
The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become false.
零值(对于整数、浮点和无作用域枚举)以及空指针和指向成员的空指针值变为假。 All other values become true.
所有其他值都变为真。
Source on cppreference cppreference 上的来源
This leads to the following conclusions:这导致以下结论:
a == 0
is the same as !a
, because a
is converted to a boolean and then inverted, which equals !(a != 0)
. a == 0
与!a
相同,因为a
被转换为布尔值然后反转,等于!(a != 0)
。 The same goes for b. b 也是如此。
c==1
will become only true when c
equals 1. Using the conversion (bool)c
would yield true
when c != 0
not just if c == 1
. c==1
仅在c
等于1 时才变为真。使用转换(bool)c
将在c != 0
时产生true
,而不仅仅是在c == 1
。 So it can work, because one usually uses the value 1 to represent true
, but it's not garantued.所以它可以工作,因为人们通常使用值 1 来表示
true
,但它没有保证。
a != b
is the same as a xor b
when a
and b
ar boolean expressions.当
a
和b
布尔表达式时, b
a != b
与a xor b
相同。 It's true, when one value or the other is true, but not both.这是真的,当一个值或另一个为真时,但不是两者都为真。 In this case the left hand side
(a==0 && b==0)
is boolean, so the right hand side c
is converted to boolean too, thus, both sides are interpreted as boolean expressions, thus !=
is the same as xor
in this case.在这种情况下,左边
(a==0 && b==0)
是布尔值,所以右边c
被转换为布尔值,因此,两边都被解释为布尔表达式,因此!=
与在这种情况下xor
。
You can check all of this yourself with the truthtables that the other answers provided.您可以使用其他答案提供的真值表自行检查所有这些。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.