标签:
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import java.util.regex.Pattern; /** * @author tutu * @version establish time:2015-3-19 下午2:50:51 * @class explain: */ public class BaseCalc { /** * 排列组合 * @param m * @param n * @return */ public static long calc(long m,long n){ long result =1; for(int i=1;i<=n;i++){ result=result * (m-n+i)/i; } return result; } /** * 已经测试通过 * @param args */ public static void main(String[] args) { //调用方式如下 int NUM = 0; /* Scanner input = new Scanner(System.in); System.out.println("请输入X个数,用逗号分割:"); String str = input.nextLine(); String[] datas = str.split(","); System.out.println("请输入数字Y:"); NUM = input.nextInt();*/ String str ="1,2,3,4,5"; String[] datas= str.split(","); NUM=2; if (NUM > datas.length) { System.out.println("输入的Y必须小于等于X!"); return; } //combine(Arrays.asList(datas),NUM); } /** * 递归原理实现 * * * 排列组合[1,2,3,4,5] 选择 num 个进行无重复组合 * @param data * @param num * @return */ public static List<List<Object>> parade(List<Object> data, int num) { List<List<Object>> result = new ArrayList<List<Object>>(); if (num == 1) { //只排一个元素的时候(递归结束条件) for (Object s : data) { List<Object> l = new ArrayList<Object>(); l.add(s); result.add(l); //每个元素分别保存到结果集 } return result; //并返回结果集 } for (int i=0; i<data.size(); i++) { //num>1,即排多个元素的时候,循环 List<Object> list = new ArrayList<Object>(data); list.remove(i); //去掉当前循环的元素作为下次递归的参数,即剩余的元素做递归 List<List<Object>> sub = parade(list, num-1); //递归调用 for (List<Object> l : sub) { //然后循环递归得到的结果 l.add(0, data.get(i)); //把当前元素排在每个结果的前面 result.add(l); //并保存到结果集 } } return result; //最后返回结果集 } /** * temp测试调用 * * 指定集合 指定个数无重复组合 * * 例: * 排列组合[1,2,3,4,5] 选择 num 个进行无重复组合 * @param list * @param num */ private static void combine(List<Object> list,int num ) { TreeSet<Object> set = new TreeSet<Object>(); for(Object str : list) { set.add(str); } ArrayList<TreeSet<Object>> subset = getSubset(set,num); for(TreeSet<Object> ts : subset) { System.out.println("[ts] --------->"+ts); } } private static Object[] getBinaryValue(TreeSet<Object> set) { int size = set.size(); int m = (int) Math.pow(2, size) - 1; Object[] result = new Object[m + 1]; for (int i = m; i > -1; i--) { StringBuffer sb = new StringBuffer(Integer.toBinaryString(i)); int length = sb.length(); if (length < size) { for (int j = 0; j < size - length; j++) { sb.insert(0, "0"); } } result[i] = sb.toString(); } return result; } public static ArrayList<TreeSet<Object>> getSubset(TreeSet<Object> set,int NUM) { ArrayList<TreeSet<Object>> result = new ArrayList<TreeSet<Object>>(); Object[] items = new Object[set.size()]; int i = 0; for (Object item : set) { items[i++] = item; } Object[] binaryValue = getBinaryValue(set); //堆栈原理 : [00000, 00001, 00010, 00011, 00100............... 11111] for (int j = 0; j < binaryValue.length; j++) { Object value = binaryValue[j]; TreeSet<Object> subset = new TreeSet<Object>(); for (int k = 0; k < ((String) value).length(); k++) { if (((String) value).charAt(k) == ‘1‘) subset.add(items[k]); } if(subset.size() == NUM) result.add(subset); } /* for (int j = 0; j < binaryValue.length; j++) { Object value = binaryValue[j]; TreeSet<Object> subset = new TreeSet<Object>(); for (int k = 0; k < ((String) value).length(); k++) { if (value.charAt(k) == ‘1‘) subset.add(items[k]); } if(subset.size() == NUM) result.add(subset); }*/ return result; } } //---------------------------------------------------------------------------------------------- 指定个数排列无重复组合 : Object[] num = new Object[]{1,2,3,4,5}; 指定个数必须小于num 长度 import java.util.ArrayList; import java.util.List; /** * 排列组合 *@date: 2015-11-16 *@author: tutu *@annotation: 组合算法 本程序的思路是开一个数组,其下标表示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 */ public class CombineStatisAnyThree { public static void main(String[] args) { CombineStatisAnyThree s = new CombineStatisAnyThree(); s.printAnyThree(); } public void printAnyThree(){ Object[] num = new Object[]{1,2,3,4,5}; try { List mList=combine(num,4); for(int i=0;i<mList.size();i++){ Object[] a = (Object[]) mList.get(i); for(int j=0;j<a.length;j++){ System.out.print(a[j]+" "); } System.out.println(); } System.out.println("--[mList.size]--------->"+mList.size()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 从n个数字中选择m个数字 * @param a * @param m * @return * @throws Exception */ public List combine(Object[] a,int m) throws Exception{ int n = a.length; if(m>n){ throw new Exception("错误!数组a中只有"+n+"个元素。"+m+"大于"+2+"!!!"); } List<Object> result = new ArrayList<Object>(); int[] bs = new int[n]; for(int i=0;i<n;i++){ bs[i]=0; } //初始化 for(int i=0;i<m;i++){ bs[i]=1; } boolean flag = true; boolean tempFlag = false; int pos = 0; int sum = 0; //首先找到第一个10组合,然后变成01,同时将左边所有的1移动到数组的最左边 while(flag){ sum = 0; pos = 0; tempFlag = true; result.add(merge(bs,a,m)); for(int i=0;i<n-1;i++){ if(bs[i]==1 && bs[i+1]==0 ){ bs[i]=0; bs[i+1]=1; pos = i; break; } } //将左边的1全部移动到数组的最左边 for(int i=0;i<pos;i++){ if(bs[i]==1){ sum++; } } for(int i=0;i<pos;i++){ if(i<sum){ bs[i]=1; }else{ bs[i]=0; } } //检查是否所有的1都移动到了最右边 for(int i= n-m;i<n;i++){ if(bs[i]==0){ tempFlag = false; break; } } if(tempFlag==false){ flag = true; }else{ flag = false; } } return result; } private Object[] merge(int[] bs,Object[] a,int m){ Object[] result = new Object[m]; int pos= 0; for(int i=0;i<bs.length;i++){ if(bs[i]==1){ result[pos]=a[i]; pos++; } } return result ; } }
标签:
原文地址:http://my.oschina.net/xiuzhu521/blog/531628