組合

在數學中,咱們學習了,排列組合,排列是有序的,組合是無順序的。在作算法題時,咱們也會遇到這種。
so,今天來理下,怎麼寫組合。java

舉個例子,桌子上有3個球A,B,C,咱們取2個,無放回的取,有幾種狀況?算一下:也就是C(3,2)=3。算法

須要解決的問題

那麼先理下思路,咱們須要解決哪幾個問題:數組

  1. 要怎麼表示3個數是否被取了呢,我想,弄一個int數組把他們的初值置爲0,就像int a = {0,0,0},若是他被取了,就把它置爲1,三個int分別表明ABC。
  2. 而後就是從箱子裏取球,是組合是吧。
  3. 最後,知足條件,輸出咱們獲得的組合。

方案

第一步,咱們已經解決了,怎麼表示球被取出來了。
第二步,組合:
咱們想下,如下場景:函數

  • 從桌子上取A,那麼就是BC求組合,取B,就是AC求組合,取C,就是AB求組合
  • 繼續重複,求BC的組合,就是取B出來,求C的組合,再像這樣繼續套娃。。。。都是調用的同一個方法,可想而知,是一個遞歸。

那麼定義一個函數,它的做用是從a中取球,取到知足條件輸出組合。再定義一個index,表示我取得是哪個球。以後,咱們取球,若是要選,把a[index]置爲1,參數curr表示已經取了多少個球,因此也須要+1,而後再去取下一個球。如此反覆。學習

固然咱們也能夠不取這個球,不取這個球,就要把它置爲0,可是須要index++,由於不取這個球,那仍是須要去取下一個球,好比不取A,可是咱們仍是要去BC。code

緊接着找到遞歸出口,也就是取完2個球,或者3個球都被取完了。獲得以後,就把它打印出來。也就是調用show(a[])方法。遞歸

show方法:遍歷i數組,若是a[i]==1,即咱們取了,就把他輸出。(char)('A'+i)+" "這也是個小細節。索引

代碼

/*從5個小球中取出三個小球*/
public class 組合 {
    static int count;
    //很明顯是一個組合問題,不用考慮排列,排列的話,就能夠用全排列
    public static void main(String[] args) {
        int a[] = {0,0,0};
        method1(a,0,2,0);
        System.out.println(count);
    }

    /**
     * 做用: 從a中取球,取到2個球有哪幾種組合
     *
     * @param a 數組a表示當前被選中的數
     * @param index 當前被選中的數的索引
     * @param sum  要選中多少個數
     * @param curr  當前已經選中了多少個數
     */
    private static void method1(int a[], int index, int sum, int curr) {
        if (curr == sum){
            show(a);
            count++;
            return;
        }
        //若是數組都選完了,就不能選了,之因此index == a.length,是由於最後一個也要被選
        if (index == a.length){
            return;
        }
        //當前位置要選,將這個位置改成1
        a[index] = 1;
        //判斷下一個數是否要選
        method1(a,index+1,sum,curr+1);
        //當前這個位置不選,將這個位置改成0
        a[index] = 0;
        method1(a,index+1,sum,curr);

    }

    private static void show(int[] a) {
        for (int i =0; i < a.length;i++){
            if (a[i] == 1 ){
                System.out.print((char)('A'+i)+" ");//變成char與int相加爲int,因此再把它變成char
            }
        }
        System.out.println();
    }
}
相關文章
相關標籤/搜索