排列组合问题(n取m)
来源:互联网 发布:java 格式化xml字符串 编辑:程序博客网 时间:2024/05/17 02:22
首先先写一下自己的感想:代码运行效率快,但是难以理解,且很难写,非递归算法。
组合算法思路:
1.建立一个新数组,其下标表示1到m个数,数组元素的值为1表示其下标 代表的数被选中,为0则没选中。
2.初始化,将数组前n个元素置1,表示第一个组合为前n个数。
3.从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为 “01”组合,同时将其左边的所有“1”全部移动到数组的最左端。
4.重复步骤3,直至当第一个“1”移动到数组的m-n的位置,即n个“1”全部移动到最右端时,就得到了最后一个组合
附录代码:
import java.util.ArrayList;import java.util.List;/** * 组合算法 * * @author ddh * @date 2015-10-07 13:04 */public class Combination {// 组合算法 // 本程序的思路是开一个数组,其下标表示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 31 1 0 1 0 // 1 2 41 0 1 1 0 // 1 3 40 1 1 1 0 // 2 3 40 1 1 0 1------>1 1 0 0 1 // 1 2 51 0 1 0 1 // 1 3 50 1 1 0 1 // 2 3 50 1 0 1 1------->1 0 0 1 1 // 1 4 50 1 0 1 1 // 2 4 50 0 1 1 1 // 3 4 5*/public List<char[]> combine(char[] a, int m){List<char[]> result = new ArrayList<char[]>();int n = a.length;if(n < m){System.out.println("n="+n+" < m="+m+",请重新输入!");return null;}//新建标志数组,并初始化int[] flags = new int[n];//n个位置都置为0for(int i=0; i < n; i++){flags[i] = 0;}//前m个位置置为1for(int i=0; i < m; i++){flags[i] = 1;}boolean bool = true;boolean tempBool = false;int pos = 0;int sum = 0;do{sum = pos = 0;tempBool = true;result.add(getMChar(a, flags, m));//首先找到第一个10组合,然后变成01,同时将左边所有的1移动到数组的最左边for(int i=0; i < n-1; i++){if(flags[i]==1 && flags[i+1] == 0){flags[i] = 0;flags[i+1] = 1;pos = i;break;}} //将左边的1全部移动到数组的最左边 for(int i=0;i<pos;i++){ if(flags[i]==1){ sum++; } } for(int i=0;i<pos;i++){ if(i<sum){ flags[i]=1; }else{ flags[i]=0; } } //检查是否都移动了最右边for(int i = n-m; i < n; i++){if(flags[i] == 0){tempBool = false;break;}} if(tempBool == false){ bool = true; }else{ bool = false; }}while(bool);result.add(getMChar(a, flags, m));return result;}private char[] getMChar(char[] a, int[] flags, int m) {char[] item = new char[m];int index = 0;for(int i=0; i < flags.length; i++){if(flags[i] == 1){item[index++] = a[i];}}return item;}//打印函数public void print(List<char[]> list){for(int i=0; i < list.size(); i++){char[] cs = list.get(i);for(int j=0; j < cs.length; j++){System.out.print(cs[j]+" ");}System.out.println();}}public static void main(String[] args) {char[] cs = {'a','b','c','d','e','f'};int m = 5;Combination cb = new Combination();cb.print(cb.combine(cs, m));}}
0 0
- 排列组合问题(n取m)
- TODO:排列组合问题:n个数中取m个
- 排列组合问题:n个数中取m个(Golang实现)
- C++ 排列组合—N个数中取M个数
- 排列组合n个元素中选取m个元素
- 取数字问题(M*N)
- 排列组合 C(n,m)
- 排列组合 C(n,m)
- Java 实现m个数全排列组合以及从M中选取N个数(有序)
- 排列组合 "n个球放入m个盒子m"问题 总结
- (转)排列组合 "n个球放入m个盒子m"问题 总结
- 排列组合 "n个球放入m个盒子m"问题 总结(转)
- 排列组合 "n个球放入m个盒子m"问题 总结
- 排列组合 "n个球放入m个盒子m"问题 总结
- 数学排列组合算法 P(N,M) C(N,M)
- 算法:排列组合之C(N,M)
- 排列组合 A(n, m) 字典序
- c# C(m,n) 排列组合算法
- iOS封装的三个步骤
- 对php的简单概括
- Android串口通信:串口读写实例
- FZU 10月月赛
- 命令行整理
- 排列组合问题(n取m)
- php学习基础篇之文件函数库,序列化数据,文件包含
- hdu 2879 HeHe 数论 积性函数 优化技巧
- Codeforces Round #324 A Olesya and Rodion
- 存储区划分
- 《Metasploit渗透测试魔鬼训练营》 之 SQL注入
- Longest Palindromic Substring
- Gradle-使用Gradle构建和测试-3-Ant and Gradle(一)
- 冷备份与热备份、双机热备与容错