利用格雷码找出集合的所有非空子集

前言

最近在实现论文《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;
            }
        }

参考

参考博文:http://blog.csdn.net/syzcch/article/details/7899691

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值