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