本文地址:http://blog.csdn.net/spch2008/article/details/9633585
参考自:子集生成算法
生成n个元素的子集,我认为可以这样理解:有n个不同的桶,编号1~n,每个桶最多放置一个球。遍历一遍桶,可以将球放入也可以不放入,这样,
在遍历结束后,收集放置元素的桶,打印其编号,即得到一个子集。
而放与不放有2种选择,所以共有2^n个子集,这样,可以采用二进制的形式。
示例:3个元素
000 3个桶都不放球,空集
001 第一个放球,{1}
010 第二个放球,{2}
011 第一、二放球,{1,2}
…… 依次类推
思路:从右至左,找到第一个0,记位置为pos,将pos置1,且将pos后(不含pos)元素全部置0,得到一个集合。
代码:
void printSeq(int *arr, int *tool, int len)
{
cout << "{ ";
for(int i = 0; i < len; i++)
{
if(tool[i] == 1)
cout << arr[i] << " ";
}
cout << "}";
cout << endl;
}
void generate(int *arr, int len)
{
int *tool = new int[len];
for(int i = 0; i < len; i++)
tool[i] = 0;
int pos = -1;
while(true)
{
//找0
for(int i = len-1; i>=0; i--)
{
if(tool[i] == 0)
{
pos = i;
break;
}
}
//打印集合
printSeq(arr, tool, len);
//没有找到0,出现全1情况,即全集
if(pos == -1)
break;
//置1
tool[pos] = 1;
//pos后元素全部置0
for(int i = pos+1; i < len; i++)
tool[i] = 0;
pos = -1;
}
delete [] tool;
}
int _tmain(int argc, _TCHAR* argv[])
{
int coll[] = {1,2,3};
int len = sizeof(coll) / sizeof(int);
generate(coll, len);
system("pause");
return 0;
}
结果: