前言
最近在实现论文《Learning Actionlet Ensemble for 3D Human Action Recognition》的过程中,遇到需要找出一个集合的所有子集的问题,于是在网上查找了一些资料,发现利用格雷码可以轻松地解决这类问题。过程如下:
实现过程
原理
Gray Code的思想非常的巧妙,我们可以将所产生的子集编号(范围为0~2^n-1),第一个子集为空集(编号为0,是偶数)。在其后的每个子集由前一个子集来决定,如果前一个子集编号为偶数,那么则改变前一个子集的第一位(从左边数)的二进制值(0变成1或者1变成0)作为新的子集。如果前一个子集的编号为奇数,那么就将前一个子集二进制左边数第一个1后面的那位改变其值(0变成1或者1变成0)作为新的子集。
代码
//@eleNum 集合中元素的个数
uint eleNum = 15;
//@setNum 子集的个数
int setNum = 1 << eleNum ;
//@select 输出的子集
uint select = 0;
uint mask = 1 << (eleNum - 1);
for (int j = 1; j < setNum; j++)
{
//前一个子集为奇数
if (j % 2 == 0)
{
uint maskTemp = 1 << (eleNum - 1);
while ((maskTemp&select) == 0)
{
maskTemp = maskTemp >> 1;
}
maskTemp = maskTemp >> 1;
select ^= maskTemp;
cout << select << endl;
}
//前一个子集为偶数
else
{
select ^= mask;
cout << select << endl;
}
}