高效率的排列组合算法(java实现)

  1. packageBeanUtil;
  2. importjava.util.ArrayList;
  3. importjava.util.List;
  4. importcom.work.core.exception.OurException;
  5. /**
  6. *统计任三出现的最多的几率的组合
  7. *
  8. *@authorwangmingjie
  9. *@date2009-1-1下午01:22:19
  10. */
  11. publicclassCopy_2_of_StatisAnyThree{
  12. //组合算法
  13. //本程序的思路是开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标
  14. //代表的数被选中,为0则没选中。
  15. //首先初始化,将数组前n个元素置1,表示第一个组合为前n个数。
  16. //然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为
  17. //“01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
  18. //当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得
  19. //到了最后一个组合。
  20. //例如求5中选3的组合:
  21. //11100//1,2,3
  22. //11010//1,2,4
  23. //10110//1,3,4
  24. //01110//2,3,4
  25. //11001//1,2,5
  26. //10101//1,3,5
  27. //01101//2,3,5
  28. //10011//1,4,5
  29. //01011//2,4,5
  30. //00111//3,4,5
  31. publicstaticvoidmain(String[]args){
  32. Copy_2_of_StatisAnyThrees=newCopy_2_of_StatisAnyThree();
  33. s.printAnyThree();
  34. }
  35. /**
  36. *
  37. */
  38. publicvoidprintAnyThree(){
  39. int[]num=newint[]{1,2,3,4,5,6};
  40. print(combine(num,3));
  41. }
  42. /**
  43. *从n个数字中选择m个数字
  44. *@parama
  45. *@paramm
  46. *@return
  47. */
  48. publicListcombine(int[]a,intm){
  49. intn=a.length;
  50. if(m>n){
  51. thrownewOurException("错误!数组a中只有"+n+"个元素。"+m+"大于"+2+"!!!");
  52. }
  53. Listresult=newArrayList();
  54. int[]bs=newint[n];
  55. for(inti=0;i<n;i++){
  56. bs[i]=0;
  57. }
  58. //初始化
  59. for(inti=0;i<m;i++){
  60. bs[i]=1;
  61. }
  62. booleanflag=true;
  63. booleantempFlag=false;
  64. intpos=0;
  65. intsum=0;
  66. //首先找到第一个10组合,然后变成01,同时将左边所有的1移动到数组的最左边
  67. do{
  68. sum=0;
  69. pos=0;
  70. tempFlag=true;
  71. result.add(print(bs,a,m));
  72. for(inti=0;i<n-1;i++){
  73. if(bs[i]==1&&bs[i+1]==0){
  74. bs[i]=0;
  75. bs[i+1]=1;
  76. pos=i;
  77. break;
  78. }
  79. }
  80. //将左边的1全部移动到数组的最左边
  81. for(inti=0;i<pos;i++){
  82. if(bs[i]==1){
  83. sum++;
  84. }
  85. }
  86. for(inti=0;i<pos;i++){
  87. if(i<sum){
  88. bs[i]=1;
  89. }else{
  90. bs[i]=0;
  91. }
  92. }
  93. //检查是否所有的1都移动到了最右边
  94. for(inti=n-m;i<n;i++){
  95. if(bs[i]==0){
  96. tempFlag=false;
  97. break;
  98. }
  99. }
  100. if(tempFlag==false){
  101. flag=true;
  102. }else{
  103. flag=false;
  104. }
  105. }while(flag);
  106. result.add(print(bs,a,m));
  107. returnresult;
  108. }
  109. privateint[]print(int[]bs,int[]a,intm){
  110. int[]result=newint[m];
  111. intpos=0;
  112. for(inti=0;i<bs.length;i++){
  113. if(bs[i]==1){
  114. result[pos]=a[i];
  115. pos++;
  116. }
  117. }
  118. returnresult;
  119. }
  120. privatevoidprint(Listl){
  121. for(inti=0;i<l.size();i++){
  122. int[]a=(int[])l.get(i);
  123. for(intj=0;j<a.length;j++){
  124. System.out.print(a[j]+"\t");
  125. }
  126. System.out.println();
  127. }
  128. }
  129. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值