[英]How to simplify this logical expression in a single return statement?
I have been trying to simplify this function in a single return A... B... C
statement but some cases always slip out.我一直试图在一个单一的return A... B... C
声明中简化这个 function 但有些情况总是会漏掉。 How could this checks be expressed in a logical way (with and
, or
, not
, etc.)?如何以合乎逻辑的方式表达这种检查(使用and
、 or
、 not
等)?
bool f(bool C, bool B, bool A)
{
if (A)
return true;
if (B)
return false;
if (C)
return true;
return false;
}
bool f(bool C, bool B, bool A)
{
if (A)
return true;
if (B)
return false;
if (C)
return true;
return false;
}
is equivalent to相当于
bool f(bool C, bool B, bool A)
{
if (A)
return true;
else if (B)
return false;
else if (C)
return true;
else
return false;
}
is equivalent to:相当于:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
else if (!B)
{
if (C)
return true;
else
return false;
}
else
return false;
}
is equivalent to:相当于:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
else if (!B and C)
return true;
else
return false;
}
is equivalent to:相当于:
bool f(bool C, bool B, bool A)
{
if (A or (!B and C))
return true;
else
return false;
}
is equivalent to:相当于:
bool f(bool C, bool B, bool A)
{
return (A or (!B and C));
}
If you write out all the combinations, you arrive at a table如果你写出所有的组合,你会得到一张桌子
static std::vector<bool> table{false, true, false, false, true, true, true, true};
which you can then extract the value with然后你可以用它提取价值
table[4 * A + 2 * B + C]
Taking this one step further, you could simplify to更进一步,您可以简化为
242 & (A << 4 + B << 2 + C)
Both are branchless, which is nice.两者都是无分支的,这很好。
Make a truth table制作真值表
A B C return
1 0 0 1
1 0 1 1
1 1 0 1
1 1 1 1
0 0 0 0
0 0 1 1
0 1 0 0
0 1 1 0
Then either you already see how it can be shortened or you just try something, for example:然后你要么已经看到它可以被缩短,要么你只是尝试一些东西,例如:
bool f(bool C, bool B, bool A)
{
return A || (C && not B);
}
Then write a test to see that it always returns the same.然后写一个测试,看看它总是返回相同的。 I wrote a "manual" test to see that the same truth table is produced:我写了一个“手动”测试来查看是否生成了相同的真值表:
void test(bool A, bool B, bool C){
std::cout << A << " " << B << " " << C << " " << f(C,B,A) << "\n";
}
int main()
{
for (int A = 1; A >= 0; --A){
for (int B = 0; B<2;++B){
for (int C = 0; C<2;++C){
test(A,B,C);
}
}
}
}
And indeed the output is :事实上output 是:
1 0 0 1
1 0 1 1
1 1 0 1
1 1 1 1
0 0 0 0
0 0 1 1
0 1 0 0
0 1 1 0
TL;DR: When refactoring code tests are of major importance. TL;DR:重构代码测试非常重要。 Write the test make sure it passes, then refactor in tiny steps and make sure that each tiny refactoring still passed the test.编写测试确保它通过,然后以微小的步骤重构并确保每个微小的重构仍然通过测试。
PS: Less code is not always simpler. PS:更少的代码并不总是更简单。 Depending on what the conditions actually are (and I hope in your real code they have better names than just A
, B
and C
) your original code is potentially much better at expressing the intent of the code than something that uses less lines.根据实际情况(我希望在您的实际代码中它们的名称比A
、 B
和C
),您的原始代码在表达代码意图方面可能比使用更少行的代码更好。
Alternative answer:备选答案:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
if (B)
return false;
if (C)
return true;
return false;
}
You can create a boolean matrix for this:您可以为此创建一个 boolean 矩阵:
A一种 | B乙 | C C | f(C, B, A) f(C, B, A) |
---|---|---|---|
f F | f F | f F | f F |
f F | f F | t吨 | t吨 |
f F | t吨 | f F | f F |
f F | t吨 | t吨 | f F |
t吨 | f F | f F | t吨 |
t吨 | f F | t吨 | t吨 |
t吨 | t吨 | f F | t吨 |
t吨 | t吨 | t吨 | t吨 |
The lower half evaluates to if(A)
The remainding entries are these:下半部分评估为if(A)
其余条目为:
B乙 | C C | f(C, B, A) f(C, B, A) |
---|---|---|
f F | f F | f F |
f F | t吨 | t吨 |
t吨 | f F | f F |
t吨 | t吨 | f F |
There is only one true-case here: if(!B && C)
这里只有一个真实案例: if(!B && C)
To combine these two statements you have to use or
as only one of them needs to evaluate to true
: if((A) || (!B && C))
要组合这两个语句,您必须使用or
因为只有其中一个需要评估为true
: if((A) || (!B && C))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.