会者不难,难者不会

zhangdr 2001-03-23 04:30:00
如何用递归函数实现计算包含n个元素的集合的全部子集?
...全文
213 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhangdr 2001-03-29
  • 打赏
  • 举报
回复
在这些解答中我认为lu_yb的解答给我启发最大,因此我将大部分分都给他了,希望holyfire和juneball不要生气。
rh 2001-03-28
  • 打赏
  • 举报
回复
数据结构——c++语言描述
里好象有介绍……
lu_yb 2001-03-28
  • 打赏
  • 举报
回复
to zhangdr
我程序的输入是元素的个数,程序在g++下编译通过,
你完全可以自己试一下吗。如果你只有c编译器,把
其中用new的地方改成固定长度数组就是了。
当n=3时,程序结果是:
please input n: 3
Following are the subsets:
{}
{ 1 }
{ 2 }
{ 2 1 }
{ 3 }
{ 3 1 }
{ 3 2 }
{ 3 2 1 }
输入是5的时候的结果
please input n: 5
Following are the subsets:
{}
{ 1 }
{ 2 }
{ 2 1 }
{ 3 }
{ 3 1 }
{ 3 2 }
{ 3 2 1 }
{ 4 }
{ 4 1 }
{ 4 2 }
{ 4 2 1 }
{ 4 3 }
{ 4 3 1 }
{ 4 3 2 }
{ 4 3 2 1 }
{ 5 }
{ 5 1 }
{ 5 2 }
{ 5 2 1 }
{ 5 3 }
{ 5 3 1 }
{ 5 3 2 }
{ 5 3 2 1 }
{ 5 4 }
{ 5 4 1 }
{ 5 4 2 }
{ 5 4 2 1 }
{ 5 4 3 }
{ 5 4 3 1 }
{ 5 4 3 2 }
{ 5 4 3 2 1 }
算法已经很明白,至于元素是abc还是123还是某个类的对象
自己改改就是了。
给分给分。
  • 打赏
  • 举报
回复
COOL
holyfire 2001-03-27
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <conio.h>
#define COUNT 10

char str[ COUNT + 1 ] = {0};

int Selected( int * data )
{
int count = 0;
while( *data != -1 )
{
if( *data == 0 )
count ++;
data ++;
}
return count;

}

int GetData( int index , int * data )
{
if( index == -1 )
return -1;
data += index;
while( *data != -1 )
{
if( *data )
{
int temp = *data;
*data = 0;
return temp;
}
data ++;
}
return -1;
}

int ListSubSet( int _Data , int * data , int sum )
{
int selected = Selected(data);
if( sum >= selected )
{
int Data = _Data;
while( Data != -1 )
{
str[ selected - 1 ] = Data + '0';
Data = GetData( Data , data );
if ( ListSubSet( Data , data , sum ) )
{
if( selected == sum )
{
printf( "%s\n" , str );
}
}
else
return 0;
if( Selected(data) == 0 )
return 0;
data[ Data - 1 ] = Data;
}
}
return 1;
}

void main()
{
int Data = 0;
int data[ COUNT + 1 ];

//初始化集合
for( int i = 0 ; i < COUNT ; i ++ )
data[i] = i+1;
data[ COUNT ]= -1;

//清屏
clrscr();

//计算
Data = GetData( 0 , data );
ListSubSet( Data , data , 8 );//ListSubSet( 起始元素 , 集合 , 子集的大小 );
getch();
}

只要用循环列出所有大小的子集就可以了,注意计算前要初始化集合。
juneball 2001-03-27
  • 打赏
  • 举报
回复
zhangdr()的话不要那么夸张嘛!!!
该题是否为从n个元素中取k个(包括0个)
如果是,那就班门弄斧了。
若做对了,别忘了给我加分了。
用pascal解。
procedure aa(s:set of 1..n m:integer);
begin
print(s);
for i:=m+1 to n do
aa(s+[i],i)
end;

注意调用:aa([],0)

ok了
zhangdr 2001-03-27
  • 打赏
  • 举报
回复
to lu_yb:
你能用a、b、c三个元素测试一下你的输出结果吗?
请把输出结果告诉我。
lu_yb 2001-03-27
  • 打赏
  • 举报
回复
如果我没有弄错的话,应该是n个元素的组合问题吧
先说一下解决原理,首先n个元素的子集数目是2^n,
也就是每个元素都有在子集中和不在子集中两种选择。
拿三个元素做例子,0代表在子集中,1代表不在
a b c
0 0 0 空集
0 0 1 {c}
0 1 0 {b}
0 1 1 {b,c}
1 0 0 {a}
1 0 1 {a,c}
1 1 0 {a,b}
1 1 1 {a,b,c}
注意列表的左边,其实就是二进制000到111的递增数列,
就这么简单,做一个加法,全部子集就出来了,而且肯定
没有重复。
如果一定要递归来做也一样,程序很简单
#include <stdio.h>

void subset(int n,char *a){
int alen;
alen = strlen(a);
if(n!=0){
subset(n-1,a);
sprintf(a,"%s %d ",a,n);
subset(n-1,a);
*(a+alen)=0;
}
else{
printf("%s}\n",a);
return;
}
return;
}

int main()
{
int n;
char *a;
printf("please input n: ");
scanf("%d",&n);
printf("Following are the subsets:\n");
a = new char[5*n];
strcpy(a,"{");
subset(n,a);
}
zhangdr 2001-03-26
  • 打赏
  • 举报
回复
天哪,这个问题都没人会!!!
zhangdr 2001-03-25
  • 打赏
  • 举报
回复
而且空集你好象也没考虑。
zhangdr 2001-03-25
  • 打赏
  • 举报
回复
这肯定有重复
Jessielee 2001-03-25
  • 打赏
  • 举报
回复
假设myset是个集合,myset.count表示他里面元素的个数,myset[i]表示myset里面的第i个元素,下标从0开始,myset<<myset[i]表示从myset中去掉myset[i]后剩下的集合,subset(myset)表示求myset的所有子集
subset(myset)
{
输出当前集合;
if(myset.count==1)
{
return;
}
for(int i=0;i<myset.count;i++)
{
subset(myset<<myset[i]);
}
return;
}
zhangdr 2001-03-23
  • 打赏
  • 举报
回复
不会没人能解这道题吧?
binghuodao 2001-03-23
  • 打赏
  • 举报
回复
好深奥呀

33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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