1. 程式人生 > >組合(從長度為n的字串中取m個字元)---java兩種實現方法

組合(從長度為n的字串中取m個字元)---java兩種實現方法

對於這類組合問題,雖然感覺很簡單,但是用java程式碼實現起來卻不是那麼容易的。
這其中最容易用到的應該是遞迴的思想了,這種方法也比較容易理解:
方法一:
遞迴實現程式碼:

/**
     * 可能種類在4000萬的時候時間效率為7.6s左右
     * @param headIndex:當前所要新增字元在原始字串中的index
     * @param length:當前字串長度
     * @param inStr:原始字串
     * @param res:當前字串
     * @param n:所要組合的字串長度
     */
    public static void DiguiZuhe
(int headIndex,int length,String inStr,String res,int n){ String s = res; for (int i = headIndex; i < inStr.length() + length - n; i++) { if (length <= n) { res = res + inStr.substring(i, i + 1); DiguiZuhe(i + 1, length + 1, inStr, res, n); if
(length == n) { System.out.println(res); } }else { return; } res = s; } } //-------------------------------分割線----------------------------- public static void main(String[] args) { String inStr = "abcdefg"
; int n = 3; String res = ""; DiguiZuhe(0, 1, inStr, res, n); }

方法二:

/**
     * * 具體思路:將我們的原始的字串用01陣列來代替,0表示沒有,1表示有
     * 例如:字串:abcdefg;01陣列:[1110000]->abc;[1010100]->ace
     * 長度為n的字串,取m個字元
     * 首先會初始化一個01陣列,長度為n,前m數字為1,後面n-m個數字為0
     * 然後掃描01陣列,每一次發現10的時候,都給它變為01,同時將左邊的1都移動到最左邊,已經是最左邊了就不移動,
     * 繼續掃描直到所有的1都移動到了最右邊
     * 例如:
     * 1 1 1 0 0
     * 1 1 0 1 0
     * 1 0 1 1 0
     * 0 1 1 1 0
     * 1 1 0 0 1
     * 1 0 1 0 1
     * 0 1 1 0 1
     * 1 0 0 1 1
     * 0 1 0 1 1
     * 0 0 1 1 1
     * 純演算法時間效率:可能種類在4千萬左右時間為1.2s左右
     * @param input
     * @param strNum
     * @return
     */
    public static void Combination(String input,int strNum){

        int length = input.length();
        int[] array = new int[length];
        //如果長度相等,就只有一種可能
        if (length == strNum) {
            System.out.println(input);
            return;
        }else {
            //初始化陣列
            for (int i = 0; i < length; i++) {
                if (i <= strNum -1) {
                    array[i] = 1;
                }else {
                    array[i] = 0;
                }
            }
        }
        while(isContainOneZero(array)){
            transform(array);
            //將01組成的陣列轉化為字串,本來這種演算法比較高效的,但是在這裡轉為String字串的時候(當資料量特別大的時候)
            //主要時間開銷就在這裡了
            StringBuffer res = new StringBuffer();
            for (int i = 0; i < array.length; i++) {
                if (array[i] == 1) {
                    //拼接起來
                    res.append(input.charAt(i));
                }
            }
            System.out.println(res.toString());
        }
    }
    /**
     * 驗證是否包含10
     * @param array
     * @return
     */
    public static boolean isContainOneZero(int[] array){

        for (int i = 0; i < array.length - 1; i++) {
            if (array[i] == 1 && array[i + 1] == 0) {
                return true;
            }
        }
        return false;
    }
    /**
     * 驗證是否所有的1都移到了最左邊
     * @param array
     * @param i
     * @return
     */
    public static boolean validate(int[] array,int i){

        for (int j = 0; j < i; j++) {
            if (array[j] == 0 && array[j + 1] == 1) {
                return true;
            }
        }
        return false;
    }
    /**
     * 轉換陣列
     * @param array
     */
    public static void transform(int[] array){

        for (int i = 0; i < array.length - 1; i++) {
            if (array[i] == 1 && array[i + 1] == 0) {
                swap(array, i, i + 1);
                int n = getOneNum(array, i);
                for (int j = 0; j < i; j++) {
                    if (j <= n - 1) {
                        array[j] = 1;
                    }else {
                        array[j] = 0;
                    }
                }
                return;
            }
        }
    }
    /**
     * 獲取1的數量
     * @param array
     * @param i
     * @return
     */
    public static int getOneNum(int[] array,int i){
        int num = 0;
        for (int j = 0; j < i; j++) {
            if (array[j] == 1) {
                num++;
            }
        }
        return num;
    }
    /**
     * 交換方法
     * @param array
     * @param a
     * @param b
     */
    public static void swap(int[] array,int a,int b){

        array[a] = array[a] + array[b];
        array[b] = array[a] - array[b];
        array[a] = array[a] - array[b];     
    }