求子集

前一段时间在项目中需要用到求子集的方法,在网上看到的用bitset求子集的方法,后经改造自己写了个求子集的模板,在此记录以备后用。


用bitset求子集的原始方法:

for(int i = 0; i < (1 << n); i++)

{

     bitset<n> bit(i);

     for(int j = bit.size() - 1; j >= 0; j--)

         cout<<bit[j];

    cout<<endl;

}

 

以下是根据上述方法的实现的求子集的模板,所有实现放在一个.h文件

 

#ifndef _SUBSET_H

#define _SUBSET_H

#include <vector>

#include <bitset>

#define BIT_MAX_LENGTH  255

 

enum

{

     SUBSET_TOTAL = 0xffff0000 | 1<<8, //全集

     SUBSET_PROPER = 0xffff0000 | 1<<9, //真子集

     SUBSET_NONVOID = 0xffff0000 | 1<<10, //非空子集

    SUBSET_EQ = 0xffff0000 | 1<<11, //指定子集元素个数的子集

    SUBSET_LE = 0xffff0000 | 1<<12, //小于等于指定子集元素个数的子集

    SUBSET_GE = 0xffff0000 | 1<<13, //大于等于指定子集元素个数的子集

    SUBSET_LE_NONVOID = SUBSET_LE | SUBSET_NONVOID, //小于等于指定子集元素个数且非空的子集

    SUBSET_GE_PROPER = SUBSET_GE | SUBSET_PROPER, //大于等于指定子集元素个数且为真子集

    SUBSET_PROPER_NONVOID = SUBSET_PROPER | SUBSET_NONVOID, //非空真子集

};

 

template<typename T>
static void SubSetCore(std::vector<T> &vec, std::vector< std::vector<T> > &subVec, unsigned int item_count, unsigned int set_flag)
{

#define condition_total                          (true)
#define condition_proper                      (bit.count()!=n)
#define condition_nonvoid                    (bit.count()!=0)
#define condition_proper_nonvoid     (bit.count()!=n&&bit.count()!=0)
#define condition_eq                             (bit.count()==item_count)
#define condition_le                               (bit.count()<=item_count)
#define condition_le_nonvoid              (bit.count()<=item_count&&bit.count()!=0)
#define condition_ge                             (bit.count()>=item_count)
#define condition_ge_proper              (bit.count()>=item_count&&bit.count()!=n)

#define if_condition(condition) if((condition)){\
                                    std::vector<T> temp;\
                                    for(int j=bit.size()-1;j>=0; j--)\
                                        if (bit.test(j))\
                                            temp.push_back(vec[j]);\
                                    subVec.push_back(temp);}

#define for_each_condition(condition) {for(int i=0;i<(1<<n);i++){\
                                            std::bitset<BIT_MAX_LENGTH> bit(i);\
                                            if_condition((condition))}}
    const unsigned int n = vec.size();

    switch(set_flag)
    {
        case SUBSET_PROPER:
            for_each_condition(condition_proper);
            break;
        case SUBSET_NONVOID:
            for_each_condition(condition_nonvoid);
            break;
        case SUBSET_PROPER_NONVOID:
            for_each_condition(condition_proper_nonvoid);
            break;
        case SUBSET_EQ:
            for_each_condition(condition_eq);
            break;
        case SUBSET_LE:
            for_each_condition(condition_le);
            break;
        case SUBSET_LE_NONVOID:
            for_each_condition(condition_le_nonvoid);
            break;
        case SUBSET_GE:
            for_each_condition(condition_ge);
            break;
        case SUBSET_GE_PROPER:
            for_each_condition(condition_ge_proper);
            break;
        case SUBSET_TOTAL:
        default:
            for_each_condition(condition_total);
            break;
    }
    return;

 }

//求子集模板函数

template<typename T>bool SubSet(std::vector<T> &vec, std::vector< std::vector<T> > &subVec, unsigned int flag=SUBSET_TOTAL)

{

    unsigned int item_count    = flag & 0xff;

    unsigned int set_flag = (flag&0xffffff00) ? flag&0xffffff00 : SUBSET_EQ;

    if (item_count > vec.size())

        return false;

    if (vec.empty())

        return false;

    SubSetCore(vec, subVec, item_count, set_flag);

    return true;

}

 

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值