当前位置: 首页 >> 程序设计 >> 数据结构和算法 >> 高效率的排列组合算法
 

高效率的排列组合算法

作者:      来源:     发表时间:2006-05-29     浏览次数:      字号:    

1。最近一直在考虑从m个数里面取n个数的算法。最容易理解的就是递归,但是其效率,实在不能使用。一直找寻中,今日得果

2。算法来源与互联网

组合算法  
  本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标  
  代表的数被选中,为0则没选中。    
  首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。    
  然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为  
  “01”组合,同时将其左边的所有“1”全部移动到数组的最左端。    
  当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得  
  到了最后一个组合。    
  例如求5中选3的组合:    
  1   1   1   0   0   //1,2,3    
  1   1   0   1   0   //1,2,4    
  1   0   1   1   0   //1,3,4    
  0   1   1   1   0   //2,3,4    
  1   1   0   0   1   //1,2,5    
  1   0   1   0   1   //1,3,5    
  0   1   1   0   1   //2,3,5    
  1   0   0   1   1   //1,4,5    
  0   1   0   1   1   //2,4,5    
  0   0   1   1   1   //3,4,5  

全排列算法  
   
  从1到N,输出全排列,共N!条。  
  分析:用N进制的方法吧。设一个N个单元的数组,对第一个单元做加一操作,满N进  
  一。每加一次一就判断一下各位数组单元有无重复,有则再转回去做加一操作,没  
  有则说明得到了一个排列方案。

comes from:/blog.csdn.net/MaybeHelios

责任编辑 webmaster

 
 
 
 
 
评论更多>>
 
这是我对上面算法写的程序. /*************从n个数中选m个,打印所组合情况*************/ int f(m,n) /*求组合情况个数,递归算法*/ { if(m==0||m==n)return 1; else if(m==1)return n; else return f(m-1,n-1)+f(m,n-1); } /********************************************************/ main() { int i,j,k,t,h,u; int m,n,temp; int count=0; int a[100]; printf("please input m,n(m<=n):") ; scanf("%d,%d",&m,&n); for(i=0;i<n;i++) a[i]=0; for(i=0;i<m;i++) a[i]=1; /*1表示选中,否则未选中*/ temp=f(m,n); /*用temp记录应该循环的次数*/ for(k=0;k<temp;k++) { for(t=0;t<n;t++) printf("%3d",a[t]); printf(" No.%2d",++count); printf("\n"); i=0;j=1; while(!(a[i]==1&&a[j]==0)) {i++ ;j++;} a[i]=0;a[j]=1; for(h=0;h<i;h++)/*将i(当前交换的值下标)左边的所有1移到最左边*/ { if(a[h]==1) { a[h]=0;a[u++]=1; } } u=0;h=0; /*重新置0,u,h仅作一次计数使用*/ } getch(); } #include <stdio.h> __int64 comb(int n,int k){ __int64 total = 0; int *c = new int[n], num0 = 0, num1 = 0, i, j, p = 1; for(i = 0; i < k; i++) c[i] = 1; for(;i < n; i++) c[i] = 0; while(p){ num0 = 0; num1 = 0; p = 0; for(i = 0; i < n-1; i++){ if(c[i] == 0) num0++; else num1++; if(c[i] == 1 && c[i+1] == 0){ num1--; c[i] = 0; c[i+1] = 1; for(j = 0; j <num1; j++) c[j] = 1; for(; j < i; j++) c[j] = 0; p = 1; total++; break; } } } return total+1; } int main(){ int n, k; while(!(n == 0 && k == 0)){ scanf("%d%d", &n, &k); printf("%I64d\n",comb(n,k)); } return 0; } 我按上面算法写的程序,怎么效率不高呢?请大侠指教,不胜感激!
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •