方法一:
對於任意一個元素,都可以使用一個bit位表示該元素的存在與否,例如:
集合{a, b, c},可以使用{1, 1, 1}表示{a, b, c},{1, 0 , 1}表示{a,c}。
故可以使用一個整型變量來映射整個集合,從000…000 ~ 111…111,分別表示不同的情況,一共有 種情況。我們只需要從000…000開始,每次加1,就可以獲得相應的子集,打印即可。
需要注意的是,由於該方法使用整型變量來映射集合,所以該方法僅局限於集合個數小於整型數位數(一般為32)的情況。
void print_subset_1(vector<int> arr,int mark)
{
if(mark == 0)
cout << "空集";
for(int i=0;i<arr.size();i++)
{
if(((1 << i) & mark) != 0)
{
cout << arr[i] << ends;
}
}
cout << endl;
}
void subset_1(vector<int> arr)
{
if(arr.size() == 0 || arr.size() > 31)
return;
int end = (1 << arr.size()) - 1;
for(int i=0; i<=end; i++) //000...000~111...111
{
print_subset_1(arr,i);
}
}
方法二:
也是使用0和1來標記一個元素是否存在。但這次是用一個布爾型的數組來映射集合而不是一個整型變量,這樣對集合的個數就沒有限制了。通過遞歸將所有的子集打印出來即可。
void print_subset_2(vector<int> arr,bool *mark)
{
bool allZero = true;
for(int i=0;i<arr.size();i++)
{
if(mark[i] == 1)
{
allZero = false;
cout << arr[i] << ends;
}
}
if(allZero)
cout << "空集";
cout << endl;
}
void subset_2_1(vector<int> arr,bool **mark,int index)
{
if(index > arr.size()-1)
print_subset_2(arr,*mark);
else
{
(*mark)[index] = 1;
subset_2_1(arr,mark,index+1);
(*mark)[index] = 0;
subset_2_1(arr,mark,index+1);
}
}
void subset_2(vector<int> arr)
{
if(arr.size() == 0)
return;
bool *mark = new bool[arr.size()];
memset(mark,0,arr.size());
subset_2_1(arr,&mark,0);
}
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。