排列組合算法(JAVA實現)

組合算法實現 java


     從m個數裏面取n個數的算法。最容易理解的就是遞歸,可是其效率過低。

實現方法一:
面試

// 組合算法 
// 本程序的思路是開一個數組,其下標表示1到n個數,數組元素的值爲1表示其下標 
// 表明的數被選中,爲0則沒選中。 
// 首先初始化,將數組前m個元素置1,表示第一個組合爲前n個數。 
// 而後從左到右掃描數組元素值的「10」組合,找到第一個「10」組合後將其變爲 
// 「01」組合,同時將其左邊的全部「1」所有移動到數組的最左端。 
// 當第一個「1」移動到數組的n-m的位置,即m個「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 

import java.util.ArrayList; 
import java.util.List; 

/** 
* 面試中遇到的問題,在網上查找資料,加上本身的總結, java 代碼實現組合的算法 
* 從n個數裏取出m個數的組合是n*(n-1)*...*(n-m+1)/m*(m-1)*...2*1 該方法比較好理解,但具體算法的分析卻有難度。 
* 
* @date
* @author  
* 
*/ 
class Zuhe { 

    /** 
    * @param  a:組合數組 
    * @param  k:生成組合個數 
    * @return  :全部可能的組合數組列表 
    */ 
    private List zuhe(int[] a, int m) { 
       Zuhe1 zuhe = new Zuhe1(); 
       List list = new ArrayList(); 
       int n = a.length; 
    
       boolean flag = false; // 是不是最後一種組合的標記 
    
       // 生成輔助數組。首先初始化,將數組前m個元素置1,表示第一個組合爲前m個數。 
       int[] tempNum = new int[n]; 
       for (int i = 0; i < n; i++) { 
        if (i < m) { 
         tempNum[i] = 1; 
    
        } else { 
         tempNum[i] = 0; 
        } 
        System.out.print(tempNum[i]); 
       } 
       print(tempNum);// 打印輔助數組 
    
       list.add(zuhe.createResult(a, tempNum, m));// 打印第一中默認組合 
    
       do { 
        int pose = 0; // 記錄改變的位置 
        int sum = 0; // 記錄改變位置 左側 1 的個數 
        // 而後從左到右掃描數組元素值的「10」組合,找到第一個「10」組合後將其變爲「01」 
        for (int i = 0; i < (n - 1); i++) { 
         if (tempNum[i] == 1 && tempNum[i + 1] == 0) { 
          tempNum[i] = 0; 
          tempNum[i + 1] = 1; 
          pose = i; 
          break; 
         } 
        } 
        print(tempNum);// 打印輔助數組 
        list.add(zuhe.createResult(a, tempNum, m));// 打印第一中默認組合 
    
        // 同時將其左邊的全部「1」所有移動到數組的最左端。 
    
        for (int i = 0; i < pose; i++) { 
         if (tempNum[i] == 1) 
          sum++; 
        } 
    
        for (int i = 0; i < pose; i++) { 
         if (i < sum) 
          tempNum[i] = 1; 
         else 
          tempNum[i] = 0; 
        } 
    
        // 判斷是否爲最後一個組合:當第一個「1」移動到數組的n-m的位置,即m個「1」所有移動到最右端時,就獲得了最後一個組合。 
        flag = false; 
        for (int i = n - m; i < n; i++) { 
    
         if (tempNum[i] == 0) 
          flag = true; 
    
        } 
       } while (flag); 
    
       return list; 
    } 
    
    // 根據輔助數組和原始數組生成 結果數組 
    public int[] createResult(int[] a, int[] temp, int m) { 
       int[] result = new int[m]; 
    
       int j = 0; 
       for (int i = 0; i < a.length; i++) { 
    
        if (temp[i] == 1) { 
         result[j] = a[i]; 
         System.out.println("result[" + j + "]:" + result[j]); 
         j++; 
    
        } 
       } 
    
       return result; 
    } 
    
    // 打印 
    public void print1(List list) { 
    
       for (int i = 0; i < list.size(); i++) { 
        System.out.println(); 
        int[] temp = (int[]) list.get(i); 
        for (int j = 0; j < temp.length; j++) { 
         System.out.print(temp[j] + " "); 
        } 
       } 
    } 
    
    // 打印整數數組的方法 
    public void print(int[] a) { 
       System.out.println("生成的輔助數組爲:"); 
       for (int i = 0; i < a.length; i++) { 
        System.out.print(a[i]); 
       } 
       System.out.println(); 
    } 
    
    public static void main(String[] args) { 
       int[] a = { 1, 2, 3, 4, 5 }; // 整數數組 
       int m = 3; // 待取出組合的個數 
       Zuhe1 zuhe = new Zuhe1(); 
       List list = zuhe.zuhe(a, m); 
       zuhe.print1(list); 
    
    } 
}


實現方法二:使用遞歸算法,但比較難於理解,摘自網上,慢慢消化
算法

/** 
* 從n個數裏取出m個數的組合是n*(n-1)*...*(n-m+1)/m*(m-1)*...2*1 
*/ 
import java.io.*; 

public class Test1 { 

    public static void main(String[] args) { 
       select(2); 
    } 
      
    
    private static void select(int k) { 
       char[] result = new char[k]; 
       subselect(0, 1, result, k); 
    
    } 
        
    
        
    private static void subselect(int head, int index, char[] r, int k) { 
       for (int i = head; i < a.length + index - k; i++) { 
        if (index < k) { 
         r[index - 1] = a[i]; 
         System.out.println("i="+(i)+";index="+(index)); 
         subselect(i + 1, index + 1, r, k); 
        } else if (index == k) { 
         r[index - 1] = a[i]; 
         System.out.println(";i="+(i)+";index="+(index)+";index==k:"+(index==k)); 
         System.out.print(i+"==="); 
         System.out.println(r); 
         subselect(i + 1, index + 1, r, k); 
        } else { 
         System.out.println("++"); 
         return;//返回到何處?奇怪 
        } 
    
       } 
    } 
    
    private static char[] a = { 'a', 'b', 'c' }; 
}
相關文章
相關標籤/搜索