我只是编程了一段时间,还没有找到一种方法来编写分支代码,涵盖两个或更多布尔值的每个可能配置,而没有任何冗余的if语句。
例如,显示所有可能结果的表格可能如下所示:
true false
---------------------
true | Thing A | Thing B |
---------------------
false | Thing C | Thing D |
---------------------
然而,我能想到的唯一能编程A但D的代码如下:
if(boolean1) {
if(boolean2)
ThingA();
else
ThingB();
}
else if (boolean2)
ThingC();
else
ThingD();
有没有办法写这个而不必为boolean2写两次检查?我知道只有一个检查可以运行一次这个代码的迭代,但是在需要担心的布尔值超过两个的情况下,这种方法可能变得非常麻烦。
答案 0 :(得分:2)
如果您的目标是消除if语句,那么指向函数的4条目查找表将是您最优雅的答案;将您的两位(布尔值)合并为一个2位值,并使用它来确定要使用的查找表条目,即在pseuodocode中:
static FunctionArrayInYourLanguage fnAr[4] {ThingA(), ThingB(), ThingC(), ThingD()}
UnsignedIntegerType manyBooleans = (boolean1 LeftShift 1) BitwiseOR boolean2
Remark: Or any other way of combining your booleans, like casting a struct of 8 bits as a uint8_t in C or vice versa
Execute fnAr[manyBooleans]();
请注意,如果您能够负担查找表空间,这种技术可以扩展到多于2个布尔值,如果您真的为每个可能的组合提供了一个函数,那么您绝对可以负担得起这个空间。
答案 1 :(得分:1)
你可以做的是使用位移创建一个掩码并引入一个开关
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <cstdint>
using namespace std;
int main() {
bool bArray[2];
for (size_t i = 0 ; i < 2 ; i++) {
cin >> bArray[i];
}
uint32_t mask = 0;
mask = bArray[0];
mask = mask << 1;
mask = mask ^ bArray[1];
switch(mask) {
case 0:
cout << "bot false" << endl;
break;
case 1:
cout << "first false, second true" << endl;
break;
case 2:
cout << "first true, second false" << endl;
break;
case 3:
cout << "both true" << endl;
break;
}
return 0;
}
你可以使用新的C ++ 11扩展使它非常优雅,你可以在其中重载文字运算符“”_和替换案例2:使用“10”_bin2int,其方式与在
中创建哈希的方式类似这里有一个完整的工作示例
http://dev.krzaq.cc/switch-on-strings-with-c11/
使用上面的信息,我能想到的最优雅的解决方案就像这样。请注意如何在编译时评估文字。你需要一个支持字符串文字的编译器来编译这个
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <cstdint>
using namespace std;
constexpr uint32_t basis = 0;
constexpr uint32_t bin2int_compile_time(char const* str,
uint32_t last_value = basis) {
return *str ?
bin2int_compile_time(str+1,(last_value << 1) ^ ((uint8_t)*str)-48) :
last_value;
}
constexpr uint32_t operator "" _bin2int(char const* p, size_t) {
return bin2int_compile_time(p);
}
uint32_t bool2int(const bool* bools, const size_t length) {
uint32_t mask = bools[0];
for (size_t i = 1 ; i < length ; i++) {
mask = mask << 1;
mask = mask ^ bools[i];
}
return mask;
}
int main() {
const size_t nBooleans = 2;
bool bArray[nBooleans];
for (size_t i = 0 ; i < nBooleans ; i++) {
cin >> bArray[i];
}
uint32_t mask = bool2int(bArray, nBooleans);
switch(mask) {
case "00"_bin2int:
cout << "both false" << endl;
break;
case "01"_bin2int:
cout << "first false, second true" << endl;
break;
case "10"_bin2int:
cout << "first true, second false" << endl;
break;
case "11"_bin2int:
cout << "both true" << endl;
break;
default:
break;
}
return 0;
}
答案 2 :(得分:0)
有面向对象的方法。
public interface Branch {
public boolean isCondition();
public void execute();
}
public class FirstThing implements Branch {
private boolean boolean1;
private boolean boolean2;
public FirstThing(boolean boolean1, boolean boolean2) {
this.boolean1 = boolean1;
this.boolean2 = boolean2;
}
@Override
public boolean isCondition() {
return boolean1 & boolean2;
}
@Override
public void execute() {
thing00();
}
}
等表项的其余部分。
将每个实现类的实例添加到List。循环遍历列表,直到isCondition()为真,然后执行()。