有效比较整数列表与C++中给定的整数
efficient comparison of list of ints with a given int in C++
有没有一种高效/优雅的方法来比较整数列表与C++中给定的整数。假设我有一个四重数字: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"。我计划做一个开关盒,因为所有这些组合都会调用不同的代码。
布尔元组为键的查找映射:
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 没有元组的默认哈希函数。
可以使用按位运算将四个测试的结果合并为单个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;
}
尝试匹配位字段。
如果我们考虑一个 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;
}
- C++模板函数,用于比较任何无符号整数和有符号整数
- 正在LLVM中检测整数比较条件
- 为什么:不同符号的整数比较只是偶尔发生?
- C++ 如何比较n个排序的整数向量以找到互元素?
- 比较C++中两个整数的最有效和最干净的方法是什么?
- 禁止指针和整数之间的比较C++
- ISO C++禁止指针和整数 [-fpermissive] [c++] 之间的比较
- Qsort() 比较结构体整数的总和
- 比较两个整数在C++中与未知 int 类型的相等性
- Qt 错误 iso c++ 禁止指针和整数之间的比较 -permissive
- 比较整数提升后的结果
- 对压缩整数进行加法、减法和比较
- 如何正确比较整数和浮点值
- 错误:ISO C++禁止在指针和整数 [-fallowive] 之间进行比较
- C++ 将二进制字符串转换为整数或比较 2 个字符串以查找差异数
- "正确"无符号整数比较
- C++,指向整数比较错误的指针
- C++指针与整数比较编译错误
- 为什么此指针/整数比较会生成分段错误
- 这是不可避免的有符号和无符号整数比较吗?