求集合子集问题的C语言实现

maybe198376 2008-03-20 10:05:13
编写一个程序,对输入的任意正整数n,输出集合{0,1,2,3,....,n-1}的所有子集
...全文
926 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Dancing_Sea 2008-03-26
  • 打赏
  • 举报
回复
由于数据较小,只有10个 < 32,有个更巧妙的方法,
采用联合体
Union
{
int i;
bool flag[32];
}

i变化
flag[16]能够遍历所有的组合.
注意取前面的几位

效率会更高一些;

对于数据过大的,就要用其他方法了。
上面所提到的算法,都没有注意采用增量式的寻找方法
在数据量很大的时候,内存是个问题:)
WhatICanDo 2008-03-25
  • 打赏
  • 举报
回复
#define Max 20

main()
{
int a[Max] = {0}, b[Max] = {0};

int i, j, m, n, k;

scanf( "%d", &k);

for(i = 1; i < k, i++)
scanf("%d", b[Max]);

m = k;

n = 2 << k;

for(i = 0; i < n; i++)
{
while(k >= 0 || a[k] == 0)
k = k - 1;

if(a[k] == 1 )
{
a[k] = 0;

for(j = k; j > m; j++)
a[j] = 0;
}

for(j = 0; j < m; j++)
{
if(a[j] == 1)

printf(" %d", b[j]);
}

printf("\n");
}
printf("{ }\n");
getch();
}


看看这个对不对?



















































































nobush 2008-03-22
  • 打赏
  • 举报
回复
RE: 7楼

输出数量超出了可显示的上限。

把它重定向到文件中看

比如:
myprog.exe > out.txt
maple604 2008-03-21
  • 打赏
  • 举报
回复
谢谢你们,真的好强啊,不知道我什么时候才能达到你们的水平!
好像有一点问题,比如我测试二楼朋友的程序,令MAX_N=10,结果total group是1023没错,可是集合不全啊,是我的显示有问题吗?还是别的原因,如第一项为{023789}而没有小于它的项了
ryfdizuo 2008-03-21
  • 打赏
  • 举报
回复

//顺序反的...
#include <stdio.h>
#include <stdlib.h>

int zuoyi(int n)
{
int i = 1<<n;
return i-1;
}
int main()
{
int k[100];
int p = 0, q,i,j;
int n;
scanf("%d",&n);
p = zuoyi(n);
for ( i = 0; i <= p; i++ )
{
j = i;
for ( q = 0; j > 0; q++ )
{
k[q] = j%2;
j = j/2;
}
printf(" { ");
while (q--)
{
if ( k[q] ) printf("%d ",q+1);
}
printf("}\n");
}
return 0;
}
pptor 2008-03-21
  • 打赏
  • 举报
回复
输出结果 n=5时

input a number:
5
{}
{1}
{2}
{1,2}
{3}
{1,3}
{2,3}
{1,2,3}
{4}
{1,4}
{2,4}
{1,2,4}
{3,4}
{1,3,4}
{2,3,4}
{1,2,3,4}
{5}
{1,5}
{2,5}
{1,2,5}
{3,5}
{1,3,5}
{2,3,5}
{1,2,3,5}
{4,5}
{1,4,5}
{2,4,5}
{1,2,4,5}
{3,4,5}
{1,3,4,5}
{2,3,4,5}
{1,2,3,4,5}
16
Press any key to continue

pptor 2008-03-21
  • 打赏
  • 举报
回复

#include <stdio.h>
#include <string.h>
#include <windows.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");
}
}
void main()
{
int n;
printf("input a number:\n");
scanf("%d", &n);
long lBegin = GetTickCount();
jisuan(n);
long lEnd = GetTickCount();
printf("%d\n",lEnd-lBegin);
}
csdn5211 2008-03-21
  • 打赏
  • 举报
回复
我还是先想到递归,因为这个问题等价于输出一个n层二叉树的所有叶子节点。
野男孩 2008-03-21
  • 打赏
  • 举报
回复
所有子集。。。。。


#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;

//输出组合
for(int i=0; i<MAX_N; i++)
{
if (g_arr[i] == 1)
{
printf("%d\t", i);
}
}
printf("\n");
}
}

int main(int argc, char* argv[])
{
for(int i=1; i<=MAX_N; i++)
Recur(g_arr, MAX_N, i);

printf("total group = %I64u\n", g_cnt);
return 0;
}



输出MAX_N=5的情况:
0
1
2
3
4
0 1
0 2
0 3
0 4
1 2
1 3
1 4
2 3
2 4
3 4
0 1 2
0 1 3
0 1 4
0 2 3
0 2 4
0 3 4
1 2 3
1 2 4
1 3 4
2 3 4
0 1 2 3
0 1 2 4
0 1 3 4
0 2 3 4
1 2 3 4
0 1 2 3 4
total group = 31
brookmill 2008-03-21
  • 打赏
  • 举报
回复
#include <stdio.h>

#define MAX 20

int results[MAX];
int step;
int numcomb;

void output()
{
int i;
for (i = 0; i < numcomb; i++)
{
printf("%3d", results[i]);
}
printf("\n");
}

void work(int lowerlimit, int upperlimit, int num)
{
int i;
for (i = lowerlimit; i <= upperlimit - num; i++)
{
results[step++] = i;
if (num > 1)
work(i + 1, upperlimit, num - 1);
if (step >= numcomb)
{
output();
}
step--;
}
}

void comb(int n, int m)
{
step = 0;
numcomb = m;
work(0, n, numcomb);
}

void subset(int n)
{
int i;
for (i = 1; i <= n; i++)
{
comb(n, i);
}
}

int main(void)
{
int n;
printf("Please input a integer between 1 and %d: ", MAX);
scanf("%d", &n);
if (n <= 0 || n > MAX)
{
printf("Input error.\n");
return 1;
}
subset(n);
return 0;
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧