如何在单个 return 语句中简化此逻辑表达式?
How to simplify this logical expression in a single return statement?
我一直在尝试在单个 return A ... B ... C
语句中简化此函数,但有些情况总是会漏掉。如何以合乎逻辑的方式表达这种检查(使用 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;
}
相当于
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;
}
相当于:
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;
}
相当于:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
else if (!B and C)
return true;
else
return false;
}
相当于:
bool f(bool C, bool B, bool A)
{
if (A or (!B and C))
return true;
else
return false;
}
相当于:
bool f(bool C, bool B, bool A)
{
return (A or (!B and C));
}
如果你写出所有的组合,你会得到 table
static std::vector<bool> table{false, true, false, false, true, true, true, true};
然后您可以使用
提取值
table[4 * A + 2 * B + C]
更进一步,您可以简化为
242 & (A << 4 + B << 2 + C)
两者都是无分支的,这很好。
讲道理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
那么要么你已经知道如何缩短它,要么你只是尝试一些东西,例如:
bool f(bool C, bool B, bool A)
{
return A || (C && not B);
}
然后写一个测试,看看它总是returns一样。我写了一个“手动”测试,看看产生了同样的道理table:
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);
}
}
}
}
确实 output is:
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:重构代码测试非常重要。编写测试确保它通过,然后在微小的步骤中重构并确保每个微小的重构仍然通过测试。
PS:更少的代码并不总是更简单。根据实际情况(我希望在你的真实代码中它们有比 A
、B
和 C
更好的名字)你的原始代码在表达意图方面可能更好代码比使用更少行的东西。
备选答案:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
if (B)
return false;
if (C)
return true;
return false;
}
您可以为此创建一个布尔矩阵:
A
B
C
f(C, B, A)
f
f
f
f
f
f
t
t
f
t
f
f
f
t
t
f
t
f
f
t
t
f
t
t
t
t
f
t
t
t
t
t
下半部分的计算结果为 if(A)
其余条目如下:
B
C
f(C, B, A)
f
f
f
f
t
t
t
f
f
t
t
f
这里只有一个true-case:if(!B && C)
要合并这两个语句,您必须使用 or
,因为只有其中一个需要评估为 true
:if((A) || (!B && C))
我一直在尝试在单个 return A ... B ... C
语句中简化此函数,但有些情况总是会漏掉。如何以合乎逻辑的方式表达这种检查(使用 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;
}
相当于
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;
}
相当于:
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;
}
相当于:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
else if (!B and C)
return true;
else
return false;
}
相当于:
bool f(bool C, bool B, bool A)
{
if (A or (!B and C))
return true;
else
return false;
}
相当于:
bool f(bool C, bool B, bool A)
{
return (A or (!B and C));
}
如果你写出所有的组合,你会得到 table
static std::vector<bool> table{false, true, false, false, true, true, true, true};
然后您可以使用
提取值table[4 * A + 2 * B + C]
更进一步,您可以简化为
242 & (A << 4 + B << 2 + C)
两者都是无分支的,这很好。
讲道理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
那么要么你已经知道如何缩短它,要么你只是尝试一些东西,例如:
bool f(bool C, bool B, bool A)
{
return A || (C && not B);
}
然后写一个测试,看看它总是returns一样。我写了一个“手动”测试,看看产生了同样的道理table:
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);
}
}
}
}
确实 output is:
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:重构代码测试非常重要。编写测试确保它通过,然后在微小的步骤中重构并确保每个微小的重构仍然通过测试。
PS:更少的代码并不总是更简单。根据实际情况(我希望在你的真实代码中它们有比 A
、B
和 C
更好的名字)你的原始代码在表达意图方面可能更好代码比使用更少行的东西。
备选答案:
bool f(bool C, bool B, bool A)
{
if (A)
return true;
if (B)
return false;
if (C)
return true;
return false;
}
您可以为此创建一个布尔矩阵:
A | B | C | f(C, B, A) |
---|---|---|---|
f | f | f | f |
f | f | t | t |
f | t | f | f |
f | t | t | f |
t | f | f | t |
t | f | t | t |
t | t | f | t |
t | t | t | t |
下半部分的计算结果为 if(A)
其余条目如下:
B | C | f(C, B, A) |
---|---|---|
f | f | f |
f | t | t |
t | f | f |
t | t | f |
这里只有一个true-case:if(!B && C)
要合并这两个语句,您必须使用 or
,因为只有其中一个需要评估为 true
:if((A) || (!B && C))