获取组合数

来源:互联网 发布:淘宝上如何找货源 编辑:程序博客网 时间:2024/05/22 05:25

参考这篇博客的方法http://blog.csdn.net/randyjiawenjie/article/details/6784355

方法思路:用一个位数组来表示组合数的一种组合情况。比如C(n,m),m个数里面,n个数的不同组合情况。可以表示成11..100...0其中1的个数代表这个数字出现在组合中,0所在的位数代表这个数字没有出现在组合中。比如,C(3,5),对于数字1到5来说,其中一种组合情况就是123,表示成位数组就是11100;另一种组合情况,比如134,表示成10110。现在通过有规律的移动每一位上的1,来找出所有的排列数,比如C(3,5)


那篇博客里给出的描述不是很清晰,我再用自己的语言描述一下,加深记忆。首先从11100开始,从左到右寻找10组合,如果找到一个10组合,就将两个位置上的1和0调换位置。并且,对于新调换位置后的那个1,对他前面的子数组里的各位元素,重复从左到右寻找10组合的过程,并调换。重复这个过程,直到子数组里不再有10组合,则向上返回,继续探测父数组的10组合,发现后,再对新交换的1前面的子数组进行探测,知道找到所有情况。


乍一看这个方法,就是一个寻找10组合并置换的方法,但他有个恼人的地方,就是原数组置换之后,只能对置换的那个1前面的子数组置换。一开始没有看清这个子数组的关系,输出的结果有很多重复项,后来增加了一个位置标记,用来告诉下一次调用,循环探测到哪个位置停止,结果就正常了。


下面是用迭代的方法的实现

import java.util.ArrayList;public class TEST{public static ArrayList<ArrayList<Integer>> alllist = new ArrayList<ArrayList<Integer>>();public static void main(String[] args){System.out.println("test:");int m = 6;int n = 3;ArrayList<Integer> arr = new ArrayList<Integer>();for(int i = 0; i< m; i++){arr.add(0);}for(int i = 0; i< n; i++){arr.set(i, 1);}rearrange(arr, m);for(int i = 0; i< alllist.size(); i++){for(int j= 0; j< alllist.get(i).size(); j++){System.out.print(alllist.get(i).get(j));System.out.print(",");}System.out.println();}}public static void rearrange(ArrayList<Integer> arr, int m){ArrayList<Integer> ins;ins = new ArrayList<Integer>();ins.addAll(arr);alllist.add(ins);for(int i = 1; i< m; i++){if(arr.get(i-1)== 1 && arr.get(i)== 0){ins = new ArrayList<Integer>();arr.set(i-1, 0);arr.set(i, 1);ins.addAll(arr);rearrange(ins, i);}}return;}}


0 0
原创粉丝点击