码迷,mamicode.com
首页 > 其他好文 > 详细

排列组合

时间:2015-11-17 17:07:14      阅读:187      评论:0      收藏:0      [点我收藏+]

标签:

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!