C++ : 二进制法生成子集

20 篇文章 0 订阅

    一个有 n 个元素的集合 (n >=0,n为整数),可以生成 2^n个子集。例如 {a,b} 可以生成4个子集    {空}、{a},{b}{a,b}

二进制法就是 从0到 2^n用二进制表示,为1的对应的数组位置元素 纳入子集集合。

例如   a = {a,b,c,d}  有 16 个子集,建立如下表

十进制数二进制数1对应的数组元素结果集
00000 
10001a[3]d
20010a[2]c
30011a[2], a[3]c,d
40100a[1]b
50101a[1],a[3]b,d
60110a[1],a[2]b,c
70111a[1],a[2],a[3]b,c,d
81000a[0]a
91001a[0],a[3]a,d
101010a[0],a[2]a,c
111011a[0],a[2],a[3]a,c,d
121100a[0],a[1]a,b
131101a[0],a[1],a[3]a,b,d
141110a[0],a[1],a[2]a,b,c
151111a[0],a[1],a[2],a[3]a,b,c,d

 

 

 /**
         * <p> 获取所有子集
         * @tparam ElemType  返回值类型
         * @tparam _InputIterator 线性表的迭代器类型
         * @param _first1      线性表的起始地址
         * @param _last1    线性表的结束地址
         * @param _null     用变量来指定返回值类型避免编译不过
         * @return  所有子集
         */
        template<class ElemType,class  _InputIterator>
        vector<vector<ElemType>> makeSubset(_InputIterator _first1, _InputIterator _last1, ElemType _null ){
            int n = _last1 - _first1;
            vector<vector<ElemType>> ret;
            // 2的n次方   1<<n
            for(int s=0;s<(1<<n);s++) {
                vector<ElemType> subRet;
                for (int i = 0; i < n; i++) {
                    if (s & (1 << i)) //1左移i位,监测s的哪一位为1,为1的话输出
                    {
                        subRet.push_back(*(_first1 + i));
//                        std::cout<<i;
                    }
                }
                ret.push_back(subRet);
//                std::cout << std::endl;
            }
            return  ret;
        }

调用示例:

#include<algorithm>
#include<iostream>
using namespace std;
int main(){
   string aaaa[3]={"7a8","2b2","3c1"};
    string string1;
    vector<vector<string>>aaRet= makeSubset(aaaa, aaaa + 3, string1);
    for (int j = 0; j < aaRet.size(); ++j) {
        cout<<"{";
        for (int i = 0; i < aaRet[j].size(); ++i) {
            cout<< aaRet[j][i] <<" ";
        }
        cout<<"}\n";
    }

}

 

{}
{7a8 }
{2b2 }
{7a8 2b2 }
{3c1 }
{7a8 3c1 }
{2b2 3c1 }
{7a8 2b2 3c1 }

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值