[经典算法] 排列组合-N元素集合的M元素子集
2015-09-25 11:41
615 查看
题目说明:
假设有个集合拥有n个元素,任意的从集合中取出m个元素,则这m个元素所形成的可能子集有那些?题目解析:
假设有5个元素的集合,取出3个元素的可能子集如下:{123}、{124}、{125}、{134}、{135}、{145}、{234}、{235}、{245}、{345}这些子集已经使用字典顺序排列,如此才可以观察出一些规则:如果最右一个元素小于m,则如上面一样的不断加1如果右边一位已至最大值,则加1的位置往左移每次加1的位置往左移后,必须重新调整右边的元素为递减顺序所以关键点就在于哪一个位置必须进行加1的动作,到底是最右一个位置要加1?还是其它的位置?
在实际撰写程式时,可以使用一个变数positon来记录加1的位置,position的初值设定为n-1,因为我们要使用队列,而最右边的索引值为最大的n-1,在position位置的值若小于m就不断加1,如果等于m了,position就减1,也就是往左移一个位置;由于位置左移后,右边的元素会经过调整,所以我们必须检查最右边的元素是否小于m,如果是,则position调整回n-1,如果不是,则positon维持不变。
程序代码:
#include<gtest/gtest.h> usingnamespacestd; voidShowResult(intdata[],intM) { for(inti=0;i<M;i++) { cout<<data[i]<<""; } cout<<endl; } intGenerateMFromN(intN,intM) { intnCount=0; if(M==0) { return1; } int*State=newint[M]; for(inti=0;i<M;i++) { State[i]=i+1; } nCount++; ShowResult(State,M); intnPos=M-1; while(State[0]<N-M+1) { if(State[M-1]==N) { nPos--; } else { nPos=M-1; } State[nPos]++; for(inti=nPos+1;i<M;i++) { State[i]=State[i-1]+1; } ShowResult(State,M); nCount++; } delete[]State; returnnCount; } TEST(Algo,tGenerateMFromN) { //3选0组合3!/(0!*(3)!)=1 ASSERT_EQ(GenerateMFromN(3,0),1); //5选3组合5!/(3!*(5-3)!)=10 ASSERT_EQ(GenerateMFromN(5,3),10); //5选5组合5!/(5!*8!)=1 ASSERT_EQ(GenerateMFromN(5,5),1); //10选2组合10!/(2!*8!)=45 ASSERT_EQ(GenerateMFromN(10,2),45); }
相关文章推荐
- 使用flume问题总结1——搭建flume+测试Syslog source
- codeforces 580D Kefa and Dishes
- classLoader和javassist
- 算法之每日一题:哥德巴赫猜想
- OWC 绘制3D柱状图
- git之 git checkout
- 网站渗透测试
- Android中Application、静态变量和Sharedpreferences的使用与区别
- 内核中的list
- LeetCode---Majority Element
- php end()函数与current()函数
- mysql合理配置连接池数量
- PRML第一章_易混淆概念-先验后验&生成判别&分类回归
- Cocos2d-x 使用物理引擎进行碰撞检测
- c#获取目录2
- Makefile好助手:pkgconfig
- 中国朝代
- Codeforces580D. Kefa and Dishes
- windows32位下安装Redis+连接PHP
- Android万能适配器