前一段时间在项目中需要用到求子集的方法,在网上看到的用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