是否有一种有效/优雅的方法来比较int中的int与C ++中的给定int。假设我有四个数字:P,Q,R,S和我需要将它们与给定的int T进行比较以得到不同的情况。
if (P == T && Q != T && R != T && S != T) case('P');
else if (P != T && Q == T && R != T && S != T) case('Q');
else if (P != T && Q != T && R == T && S != T) case('R');
else if (P != T && Q != T && R != T && S == T) case('S');
同样地,我将有6个配对案例:PQ,QR,PR ......,4个三联案件和1个四重案件。正如你所看到的,很多明确的比较!有没有一种优雅的方法来使用STL容器?
我需要其中一个案例作为我的输出:'P','Q',..,'PQ','RS',..'PQR','PQS'......'PQRS'。我打算做一个switch-case,因为所有这些组合都会调用不同的代码。
答案 0 :(得分:5)
使用带有布尔元组的查找映射作为键:
std::map<std::tuple<bool,bool,bool,bool>,value> map;
查找价值就是这样:
map.find({T==P,T==Q,T==R,T==S});
(将它包装在查找函数中以使其更容易)。
地图的价值将决定您实际需要的是什么。如果找到密钥,它可以是字符串,数值,甚至是std :: function(lambda)。
或者你也可以使用unordered_map,但是你需要自己提供一个哈希函数,因为STL没有元组的默认哈希函数。
答案 1 :(得分:3)
您可以使用按位运算将四个测试的结果合并为一个0..15
整数值。请注意,每次比较只执行一次。
获得结果值后,它可以用作数组或std::vector
的索引或关联容器中的键查找。我在这个简单的例子中使用了switch
和结果。
int mask = (P == T) << 3 | (Q == T) << 2 | (R == T) << 1 | (S == T);
switch (mask) // 0..15
{
case 15: // PQRS
break;
case 14: // PQR
break;
case 13: // PQS
break;
case 12: // PQ
break;
case 11: // PRS
break;
case 10: // PR
break;
case 9: // PS
break;
case 8: // P
break;
case 7: // QRS
break;
case 6: // QR
break;
case 5: // QS
break;
case 4: // Q
break;
case 3: // RS
break;
case 2: // R
break;
case 1: // S
break;
case 0: // none
break;
}
答案 2 :(得分:2)
尝试匹配位字段。
如果我们考虑一个4位字段0000,我们可以设置第一位,如果T==P
第二位T==Q
,依此类推:
unsigned index{(P==T?1U:0U)|(Q==T?2U:0U)|(R==T?4U:0U)|(S==T?8U:0U)};
然后只需索引到一个数组。
注意1:我注意到使用switch
相同技巧的另一个答案也可以。
注意2:您可以将此实现视为使用“完美哈希”的哈希表。
#include <iostream>
#include <string>
//Actual Solution Starts Here.
const std::string match_data[] {
"",//0000
"P",//0001
"Q",//0010
"PQ",//0011
"R",//0100
"PR",//0101
"PQ",//0101
"PQR",//0111
"S",//1000
"PS",//1001
"QS",//1010
"PQS",//1011
"RS",//1100
"PRS",//1101
"PQS",//1101
"PQRS"//1111
};
std::string match(int T, int P, int Q, int R, int S){
unsigned index{(P==T?1U:0U)|(Q==T?2U:0U)|(R==T?4U:0U)|(S==T?8U:0U)};
return match_data[index];
}
//Actual Solution Ends Here.
//The rest is a trivial test harness...
bool error{false};
int check(int T, int P, int Q, int R, int S, const std::string& expect){
const auto result{match(T,P,Q,R,S)};
if(result!=expect){
std::cout<<"Error ("<<T<<','<<P<<','<<Q<<','<<R<<','<<S<<")=="<<result<<"!="<<expect<<std::endl;
error=true;
return 1;
}
return 0;
}
int main() {
int errors{0};
errors+=check(7,1,2,3,4,"");
errors+=check(7,7,2,3,4,"P");
errors+=check(9,1,9,3,4,"Q");
errors+=check(117,1,6,117,4,"R");
errors+=check(13,1,7,3,13,"S");
errors+=check(132,132,132,132,132,"PQRS");
errors+=check(98,98,98,3,4,"PQ");
errors+=check(9876,56,87,9876,4,"R");
errors+=check(1,1,0,1,0,"PR");
errors+=check(78,78,78,78,0,"PQR");
if(errors==0&&!error){
std::cout<<"Success"<<std::endl;
}else{
std::cout<<"ERRORS: "<<errors<<std::endl;
}
return 0;
}