一个组合的问题,现在有n个选项,每个选项又分别有N0,N1,N2,N3...Nn-1个子选项,在这n个选项中分别选一个子选项,该怎么把这些选项输出

ffming 2006-04-27 10:48:28
一个组合的问题,现在有n个选项,每个选项又分别有N0,N1,N2,N3...Nn-1个子选项,在这n个选项中分别选一个子选项,该怎么把这些选项输出.
比如说有11个选项,第一个选项有5个子选项,第二个有7个子选项...
我知道总共有5*7*...
但是怎么用程序输出这几种情况,用什么算法啊,请高手指点啊
...全文
640 28 打赏 收藏 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
spirit_sheng 2006-10-14
  • 打赏
  • 举报
回复
楼主可以结贴了
39457760 2006-10-14
  • 打赏
  • 举报
回复
>>其实还有一种方法, 就是反递归, 但如果你有这么多组合, 那效率是第一位的,
>>如果for嵌套能够解决你的问题, 那这种方法是效率最高的, 三种方法的优缺点
>>如下, 你自己选择吧
什么是反递规啊?
idealguy 2006-10-08
  • 打赏
  • 举报
回复
mathe() 第二贴程序应该修改一处 index(i) -1
完整程序如下:

#include <stdio.h>
#define n 3

int index[n]={2,3,3};
int visit[n];
int i;
void main()
{ printf("\n");
for(i=0;i<n;i++) visit[i]=0;
while(1){
//Now output(visit,n);
for (i=0;i<n;i++) printf("%d ",visit[i]+1);
printf("\n");

//Now goto next visiting item
for(i=n-1;i>=0;i--)
{ if (visit[i]==index[i] -1) visit[i]=0; else break; }
if(i<0)break; //Finished
visit[i]++;
}
}


运行结果:

1 1 1
1 1 2
1 1 3
1 2 1
1 2 2
1 2 3
1 3 1
1 3 2
1 3 3
2 1 1
2 1 2
2 1 3
2 2 1
2 2 2
2 2 3
2 3 1
2 3 2
2 3 3
spirit_sheng 2006-10-07
  • 打赏
  • 举报
回复
mathe() 第一次的程序是有问题,
但mathe() 第二次贴出的程序是正确, 佩服mathe()
mmmcd 2006-10-05
  • 打赏
  • 举报
回复
index[]数组 放的相当于“进制”,第i个数逢index[i]进1

上面已经解释过了
wangxifeng920 2006-10-05
  • 打赏
  • 举报
回复
没看懂啊,
把完整的代码写上啊,
index[]数组 里面放的是什么啊,!
yyfhz 2006-08-01
  • 打赏
  • 举报
回复
支持mathe() 的代码,经典!
flyingakain 2006-07-13
  • 打赏
  • 举报
回复
spirit_sheng(老盛)

如何输出指定元素个数的组合,例如把你的代码中输出的结果改成 每2位组合的
ffming 2006-05-04
  • 打赏
  • 举报
回复
兄弟,都留下自己的QQ号码啊,我想加各位为好友啊
CD2006 2006-05-02
  • 打赏
  • 举报
回复
不好意思,上面第二个程序段落中的是:
for(i = j+1;i<=k;i++) b[i]=b[i-1] + 1;
再发现笔误,再次恳请见谅,呵呵,想睡觉了的缘故
CD2006 2006-05-02
  • 打赏
  • 举报
回复
不好意思,上面第一个程序段落中的是:
for(i = j+1;i<=n;i++) visit[i] = 0;
笔误,见谅,呵呵
CD2006 2006-05-02
  • 打赏
  • 举报
回复
呵呵,mathe()的程序写的相当的漂亮,支持支持,看的出素养相当好,学习学习

总结一下:这种题往大处归类是基本的枚举类题型(其中最经典的例如:n个数取出k个的组合的输出)

用于解这类有序枚举有非常经典的“四句话”,在下认为是一个非常经典的算法框架,就这个题:

j=n;
while(visit[j] == index[j]) j--;
visit[j] ++;
for(i = j+1;i<=n;i++) visit[j] = 0;

methe()的程序的精髓,就是这个的简化版
用上面的框架,相信很容易写出C(n,k)问题的遍历算法:

j=k;
while(b[j]=n-k+j) j--;
b[j]++;
for(i=j+1;i<=r;i++) b[i]=b[i-1]+1;

呵呵
mathe 2006-04-29
  • 打赏
  • 举报
回复
试用一下我的代码就知道了,就是你需要的。
原理如同gxqcn说的。
zhangts 2006-04-29
  • 打赏
  • 举报
回复
当n是动态时,用“多重循环”事先不知会有几重。
可以把该问题看作:一个n位的混合进制数的遍历过程即可。

gxqcn和mathe() 正解也,模拟N进制
ffming 2006-04-28
  • 打赏
  • 举报
回复
楼上的兄弟,讲一下代码的思路啊.
你的代码visit[i]++; 这个不可以这样吧
mathe 2006-04-28
  • 打赏
  • 举报
回复
遍历的问题,
int index[n];
//input index[0..n-1]

int visit[n];
int i;
for(i=0;i<n;i++)visit[i]=0;

while(1){
//Now output(visit,n);
for(i=0;i<n;i++)printf("%d ",visit[i]+1);
printf("\n");

//Now goto next visiting item
for(i=n-1;i>=0;i--){if(visit[i]==index[i])visit[i]=0;else break;}
if(i<0)break;//Finished
visit[i]++;
}
ffming 2006-04-28
  • 打赏
  • 举报
回复
mathe()的代码有问题啊
gxqcn 2006-04-28
  • 打赏
  • 举报
回复
mathe()的代码与我表达的算法是一致的,简洁而高效。
spirit_sheng 2006-04-28
  • 打赏
  • 举报
回复
10*4*5*13*3*4*6*6*9*7*12*12 = 10,189,670,400
这么多需出, 有必要吗? 建议你更改的应用方式
即使你的每个元素为最简单的整型(4字节), 需出的内容也需要:
10,189,670,400 * 4 * 12
约需要 455 GB 的存储空间
spirit_sheng 2006-04-28
  • 打赏
  • 举报
回复
其实还有一种方法, 就是反递归, 但如果你有这么多组合, 那效率是第一位的, 如果for嵌套能够解决你的问题, 那这种方法是效率最高的, 三种方法的优缺点如下, 你自己选择吧

1. For 嵌套
优点: 效率高
缺点: 扩展性差, 如你现在是有12个选项, 那如果选项数增加或减少则代码都不能适应
如果没有扩展性要求, 而且效率很重要, 则此算法是首选

2. 递归
优点: 代码简洁, 可扩展性强
缺点: 效率较低
如果效率能够满足要求, 则此算法是首选

3. 反递归
优点: 可扩展性强, 效率比递归好一些, 比FOR嵌套差
缺点: 代码比较复杂
如果要求可扩展, 而且有要求效率, 则可以选择此种方法
加载更多回复(8)

33,026

社区成员

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

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