最近看算法和数据结构书,从网上摘取了两种不同的方法:
一。不用递归
http://blog.chinaunix.net/u/15929/showart_156126.html
#include<math.h>
using namespace std;
{
char aa[]={'1','2','3','4','5','6'};
int n=sizeof(aa)/sizeof(aa[0]);
bool bo[]={0,0,0,0,0,0};
int pw=pow(2,n);
{
cout<<'{';
for(int k = 0; k < n; k++)
{
if(bo[k])
{
cout<<aa[k]<<' ';
}
}
cout<<'}'<<endl;
}
}
void change(bool*ptr, int len)
{
for(int i = 0; i < len; i++)
{
if(*ptr)
{
*ptr = 0;
}
else
{
*ptr = 1;
break;
}
ptr++;
}
}
http://hi.baidu.com/walkpigs/blog/item/3f3ad345c997613e8794733e.html
一般来说,求集合自己的一个很实用的方法是用1代表该位置的元素存在于子集中,利用0表示不存在于子集中。按照这个思路只要定义一个变量,让它从0递增到2^n-1即可,每次递增把它除以2求余数,并且将余数存储在一个大小为n的bool型数组中,在逐次检验就可以了。一下是用另一种方法实现的:
/*编写递归函数,求n个元素集合的所有子集。
不妨令集合元素为小写字母,原集合为{'a', 'b', …, 'a' + n - 1}。
输入:input.txt,仅包含整数n(1-26)。
输出:若输入合法,输出集合的所有子集;否则输出"WRONG"。
子集输出格式为每行一个子集,空集用空行表示,非空集合每个元素间用一个空格间隔,
最后一个元素之后不能有空格。例如,对n=3,可能的输出为:
―――――――――――
a
a b
a b c
a c
b
b c
c
――――――――――――-*/
#include<iostream.h>
void move(char a[], int m, int n)
{
char tmp=a[m];
for(int i=m;i<n-1;i++)
a[i]=a[i+1];
a[n-1]=tmp;
}
void faction(char a[],int k,int m)
{
if(k==m)
for(int j=0;j<2; j++,k--)
{
for(int i=0; i<k; i++)
cout<<a[i];
cout<<endl;
}
else
for(int i=0; i<m-k; i++)
{
faction(a,k+1,m-i);
move(a,k,m);
}
}
void main()
{
int m,k=0; //m为输入的整数,即集合个数
char char_a='a',a[26];
cout<<"请输入一个(1—26)的整数:";
cin>>m;
for(int i=0;i<m;i++,char_a++)
a[i]=char_a;
cout<<"----------------------------"<<endl;
if(m<1)
cout<<"WRONG!!!"<<endl;
else
{
if(m>26)
cout<<"WRONG!!!"<<endl;
else
faction(a,k,m);
}
cout<<"-----------------------------"<<endl;
}
二。递归算法