如何有效地检测4个整数变量中的对称性
How to detect symmetries in 4 integer variables efficiently?
我想在4个整数变量i,j,k
和l
中找到对称性。对称是:
- 所有四个数字都是相等的:xxxx,
- 三个数字相等:xxxy,xxyx,xyxx,yxxx
- 两对相等的数字:xxyy,xyxy,xyyx,...
- 一对相等的数字和两个不同的数字:xxyz,xyxz,xyzx,...
- 所有数字都是不同的。
所有变量在某个非连续范围内运行。如果其他语句,我使用嵌套。第一个如果检查所有变量的不等式。如果没有,则我有案例1。下一个检查是否有任何相等的对。如果不是,则为案例5。下一个如果检查三个相等的数字。如果为true,则为情况2。否则,最后一个如果检查两对相等的数字。如果为true,则为案例3,否则情况4。
if(!(i==j && j==k && k==l)){
if(i==j || i==k || i==l || j==k || j==l || k==l){
if((i==j && j==k) || (i==j && j==l) || (i==k && k==l) || (j==k && k==l)){ ...//do something
}else{
if((i==j && k==l) || (i==k && j==l) || (i==l && j==k)){
...//do something
}else{
...//do something
}
}
}else{
...//do something
}
}else{
...//do something
}
有更好的方法吗?我的意思是更好的表现,因为我必须进行数百万次测试。
与samgak相似的想法,但无需外部表。只需计算所有匹配的总和
int count = (i==j) + (i==k) + (i==l) + (j==k) + (j==l) + (k==l);
和DO switch
具有以下选择
switch (count){
case 0: //All differenct
case 1: //One same
case 2: //Two different pairs
case 3: //Three same
case 6: //All are same
}
再次,如前所述,您当前的代码在某些情况下可能会更快。特别是如果最常见的情况是所有元素相等的情况。
如果您负担得起一个小(64个字节)查找表,则可以测试每对值,并为每个比较设置您用作索引中的索引的每个值,例如:
int classifySymmetries(int i, int j, int k, int l)
{
return table[(i == j) |
((i == k) << 1) |
((i == l) << 2) |
((j == k) << 3) |
((j == l) << 4) |
((k == l) << 5)];
}
然后对返回值进行开关。您可以使用现有代码来生成表,通过对每次比较进行一些位测试,或者生成可满足从0到63的每个位模式的虚拟I J K L值。
这种方法需要常数6个比较。请记住,对4个值进行排序需要4到5个比较(有4个!= 24个可能的顺序,每个比较会产生1位信息)。但是然后,您必须根据其上排序的值进行测试。
是否使用查找表击败您当前的方法是否取决于值的分布和其他因素(例如内存访问时间),您应该介绍以确认。
一种更好的方法是使用地图:
#include <iostream>
#include <map>
using namespace std;
int main()
{
int i, j, k, l;
cin >> i >> j >> k >> l;
std::map<int, int> count;
int outcomes[5] = { 0, 0, 0, 0, 0 };
// Store the values in the map
count[i]++;
count[j]++;
count[k]++;
count[l]++;
// tally types of outcome according to the map
for(typename std::map<int, int>::iterator iter = count.begin(); iter != count.end(); ++iter)
{
outcomes[iter->second] ++;
}
// print out "1 of a kind" count, up to "4 of a kind"
// this is just for visualization
for (int i = 1; i <= 4; ++i)
{
cout << i << " of a kind = " << outcomes[i] << endl;
}
// your bit here, it checks on just the "outcomes" array
if(outcomes[4] > 0) // 4 of a kind
{
}
else if(outcomes[3] > 0) // 3 of a kind
{
}
else if(outcomes[2] > 1) // two pair
{
}
else if(outcomes[2] > 0) // one pair
{
}
else // singles only
{
}
cin.ignore();
cin.get();
return 0;
}
如果您想将其扩展到4个选择之外,则这种方法也将更加可扩展。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 用C++中的一个变量定义一个常量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 你能重载对象变量名本身返回的内容吗
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 尝试通过多个向量访问变量时,向量下标超出范围
- 试图让变量检查数组中的某些内容
- Cpp-Tuple使用带有变量的get
- 将包含C样式数组的对象初始化为成员变量(C++)
- 当vector是tje全局变量时,c++中vector的内存管理
- 通过多个头文件使用常量变量
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 执行函数时导致崩溃的变量
- 变量没有改变?通过向量的函数调用