| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 4592 人关注过本帖, 1 人收藏
标题:[分享][经验][开源]排列组合算法
取消只看楼主 加入收藏
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
收藏(1)
 问题点数:0 回复次数:10 
[分享][经验][开源]排列组合算法
//从M个数中取出N个数组合
#include <iostream>
using namespace std;
void jisuan(int a[],int m,int n,int k,int temp);
int num(int m,int n);
int jiecheng(int a);
void main()
{
int m,n;
cout<<"请输入M和N:"<<endl;
cin>>m>>n;
cout<<"一共 "<<num(m,n)<<" 种组合"<<endl;
int a[100];
jisuan(a,m,n,-1,-1);
}
void jisuan(int a[],int m,int n,int k,int temp)
{
temp++;
if(temp<n)
for(int i=k+1;i<m;i++)
{
a[temp]=i+1; //赋值
jisuan(a,m,n,i,temp); //递归调用
}
else
{
for(int j=0;j<n;j++)
{
cout<<"\t"<<a[j]; //输出
}
cout<<endl;
}
}
//计算个数
int num(int m,int n)
{
int sum;
sum=jiecheng(m)/(jiecheng(n)*jiecheng(m-n));
return sum;
}
//求阶乘
int jiecheng(int a)
{
int h=1;
for(int i=1;i<=a;i++)
h=h*i;
return h;
}

搜索更多相关主题的帖子: 算法 排列 开源 经验 分享 
2007-08-22 18:05
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
收藏
得分:0 

版主说的没错,果然是高手,我收益非浅,谢谢拉

不过以后请用中文!

现改正如下
#include <iostream>
using namespace std;
void jisuan(int a[],int m,int n,int k,int temp);
int numOfComb(int m, int n);
void main()
{
int m,n;
cout<<"请输入M和N:"<<endl;
cin>>m>>n;
cout<<"一共 "<<numOfComb(m,n)<<" 种组合"<<endl;
int a[100];
jisuan(a,m,n,-1,-1);
}
void jisuan(int a[],int m,int n,int k,int temp)
{
temp++;
if(temp<n)
for(int i=k+1;i<m;i++)
{
a[temp]=i+1; //赋值
jisuan(a,m,n,i,temp); //递归调用
}
else
{
for(int j=0;j<n;j++)
{
cout<<"\t"<<a[j]; //输出
}
cout<<endl;
}
}
//计算个数
int numOfComb(int m, int n)
{
int r=1;
int i;

for(i=1; i<=n; ++i)
{
r *= (m-i+1);
r /= i;
}

return r;
}


科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-08-23 21:28
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
收藏
得分:0 
哎哎哎,别跑题呀,怎么说到英语6级上去了!

上面 KJin 的话是跟我说的吗?

大概意思是不是让我对这个算法的核心也就是递归写个说明.让初学者理解它是怎么运行的?

其实最好的办法就是在VC++6.0中运行,设置断点,单步调试,这样你就可以知道每一步是怎么回事了!

而且每个变量在每一步是什么状态什么值都一清二楚.

如果我用文字来描述的话,可能会把初学者绕的更晕,不过我还是很愿意写一写

过两天贴出来吧.

另外,KJin在8楼指出的问题,我想可以这样理解,1...n不要理解为具体参加排列组合的数,

而应理解为"第1个"..."第n个"数

如从4个数中取2个,有一种情况是 1 2

不要理解为数就是1和2,而要理解为第1个位置上的数和第二个位置上的数.

这样你可以定义一个数组,把真正要参加排列组合的数放到里面,

然后根据上面得出的下标就可以输出真正要参加排列组合的数了!!

这个任务就交给我吧!我写写看!!都别跟我抢!!!




科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-08-24 20:17
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
收藏
得分:0 

我已经写出来了,见下面:
不过参加排列组合的数我默认为正数

#include <iostream>
using namespace std;
void jisuan(int a[],int m,int n,int k,int temp);
int numOfComb(int m, int n);
int comb[100];
void main()
{
int m,n;
int i=0;
cout<<"请输入要参加排列组合的数(以 -1 结束):"<<endl; //注意参加排列组合的数不能有-1,如果非要有-1
cin>>comb[i]; //可以把这个条件改一改
while(comb[i]!=-1)
{
i++;
cin>>comb[i];
}
m=i;
if(comb[0]==-1)
{
exit(0);
}
cout<<"请输入要提取的个数 n:"<<endl;
cin>>n;
cout<<"一共 "<<numOfComb(m,n)<<" 种组合"<<endl;
int a[100];
jisuan(a,m,n,-1,-1);
}
void jisuan(int a[],int m,int n,int k,int temp)
{
temp++;
if(temp<n)
for(int i=k+1;i<m;i++)
{
a[temp]=i+1; //赋值
jisuan(a,m,n,i,temp); //递归调用
}
else
{
for(int j=0;j<n;j++)
{
cout<<"\t"<<comb[a[j]-1]; //输出
}
cout<<endl;
}
}
//计算个数
int numOfComb(int m, int n)
{
int r=1;
int i;

for(i=1; i<=n; ++i)
{
r *= (m-i+1);
r /= i;
}

return r;
}


科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-08-24 20:55
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
收藏
得分:0 

不好意思,在看你的资料之前我就写出来了,而且有两个版本

上面那个是定义了一个全局数组comb[100],这样不用改变jisuan()的参数

下面这个是定义一个局部数组,要改变一下jisuan()的参数

#include <iostream>
using namespace std;
void jisuan(int a[],int m,int n,int k,int temp,int com[]);
int numOfComb(int m, int n);
void main()
{
int m,n;
int i=0;
int comb[100];
cout<<"请输入要参加排列组合的数(以 -1 结束):"<<endl;
cin>>comb[i];
while(comb[i]!=-1)
{
i++;
cin>>comb[i];
}
m=i;
if(comb[0]==-1)
{
exit(0);
}
cout<<"请输入要提取的个数 n:"<<endl;
cin>>n;
cout<<"一共 "<<numOfComb(m,n)<<" 种组合"<<endl;
int a[100];
jisuan(a,m,n,-1,-1,comb);
}
void jisuan(int a[],int m,int n,int k,int temp,int com[])
{
temp++;
if(temp<n)
for(int i=k+1;i<m;i++)
{
a[temp]=i+1; //赋值
jisuan(a,m,n,i,temp,com); //递归调用
}
else
{
for(int j=0;j<n;j++)
{
cout<<"\t"<<com[a[j]-1]; //输出
}
cout<<endl;
}
}
//计算个数
int numOfComb(int m, int n)
{
int r=1;
int i;

for(i=1; i<=n; ++i)
{
r *= (m-i+1);
r /= i;
}

return r;
}


科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-08-24 21:01
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
收藏
得分:0 
哇,这么一会就又有人回贴了,动作太快了吧

怎么样,我厉害吧

低调低调,很想和HJin,aipb2007等人交个朋友

可以把你们的站内邮箱告诉我吗?

然后我把我的QQ号和MSN一邮件形式告诉你们

我不想以公开的方式公布我的QQ,MSN和邮箱,所以辛苦你们一下喽.

告诉我你们的站内邮箱就行,就是本站内的邮箱

科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-08-24 21:10
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
收藏
得分:0 
不是吧,在我写上一贴的时候又有人回贴了.我不得不再写这一贴

aipb2007考虑问题挺深的,佩服佩服.

"不能在具体每一个组合上进行操作"是什么意思,具体说说

科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-08-24 21:16
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
收藏
得分:0 

明白你的意思,一开始我也打算这样来着.


科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-08-24 22:02
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
收藏
得分:0 

这个算法我在CSDN的论坛上的C++版块上也发表了,发贴人叫yonghengzhimi,其实就是我.

大家不要大惊小怪,yonghengzhimi和冰的热度是一个人,就是我

其实是汉字"永恒之迷",但是CSDN不让用汉字,只好用拼音了


科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-08-26 16:43
冰的热度
Rank: 2
等 级:禁止访问
威 望:5
帖 子:404
专家分:0
注 册:2006-12-2
收藏
得分:0 
谁给我加个精,

这都不算精品吗?

科学是永恒之迷...... 我的博客http://blog..cn/u/1267727974 阅读我的blog,懂与不懂都是收获!
2007-08-29 17:20
快速回复:[分享][经验][开源]排列组合算法
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.013348 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved