从网上搜集到了几个方法,整理如下:
方法一
#include <stdio.h>
#define MAX_N 5
int g_arr[MAX_N] = {0};
__int64 g_cnt = 0;
void Recur(int* arr, int arr_size, int req_cnt)
{
if (req_cnt > 0){
//数据没有选够,从剩下的数据中继续选
//先选中最小的
arr[0] = 1;
//然后从剩下的arr_size - 1个数据中选req_cnt-1个数据
Recur(arr+1, arr_size - 1, req_cnt-1);
//回溯一下,跳过刚才选的那个最小数的情况
arr[0] = 0;
if ((arr_size - 1) >= (req_cnt )){
Recur(arr+1, arr_size - 1, req_cnt);
}
}else{
//找到一组完整数据
++g_cnt;
//输出组合
int i;
for(i=0; i<MAX_N; i++){
if (g_arr[i] == 1){
printf("%d\t", i);
}
}
printf("\n");
}
}
int main(int argc, char *argv[])
{
int i;
for(i=1; i<=MAX_N; i++)
Recur(g_arr, MAX_N, i);
printf("total group = %I64u\n", g_cnt);
system("PAUSE");
return 0;
}
方法二
#include <stdio.h>
#include <string.h>
int a[16]={0};
unsigned long c[16]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000,0x4000,0x8000};
int b[16]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
int huanerjinzhi(long d){
int i=0;
int count=1;int k=d;
int *p;p=a;
unsigned long *q;q=c;
memset(a,0,sizeof(int)*16);
if(!k) {return 0;}
else {while(k&=(k-1)){count++;}}
while(d){
if(d&(*q)){*p=1;d&=~(*q);p++;q++;}
else{*p=0;p++;q++;}
}
return count;
}
void jisuan(long n)
{
long i, j, t;
long r;
long k=(1<<n);
for(i=0;i<k;i++){
t=huanerjinzhi(i);
printf("{");
for(r=1,j=0;r<=t;j++)
if(a[j]==1){
if(r!=t)printf("%d,",b[j]);
else printf("%d",b[j]);r++;}
printf("}\n");
}
}
int main(int argc, char *argv[])
{
int n;
printf("input a number:\n");
scanf("%d", &n);
jisuan(n);
system("PAUSE");
return 0;
}
方法三
#include <stdio.h>
//k是开始字符的位置,n是数组的长度,l是子集的位数
void subArray(int A[], int k,int l, int n);
//初始化整个子集数组
void initArray(int n);
//用于输出子集的数组
int priArray[4];
void printArray(int n);
int counter = 0;
int main()
{
int i;
int array[4] = {1, 2 , 3, 4};
//0是所有数组的子集
printf("0\n");
counter += 1;
for (i = 0; i < 4; i++)
{
initArray(4);
//递归算法需要保证从第一个元素开始的所有的元素都被遍历到
priArray[0] = array[i];
counter += 1;
printArray(1);
subArray(array, i+1, 2, 4);
}
printf("\nThe SubArray is %d\n", counter);
getchar();
return 0;
}
void subArray(int A[], int k, int l, int n)
{
int i;
if (k == n-1)
{
//n是整个数组的长度,k是整个子集的上一位字符,当k == n-1时,意味着已经是最后一个了。
priArray[l-1] = A[k];
counter += 1;
printArray(l);
}
else
{
for ( i= k; i <= n-1; ++i)
{
priArray[l-1] = A[i];
counter += 1;
printArray(l);
subArray(A, i+1, l+1,n);
}
}
}
void printArray(int n)
{
int i;
for (i = 0; i < n; i++)
{
printf("%d ", priArray[i]);
}
printf("\n");
}
void initArray(int n)
{
for (int i = 0; i<= n-1 ; i++) {
priArray[i] = 0;
}
}