使用Java實現一則演算法

來源:互聯網
上載者:User

標籤:技術分享   分享   需要   使用   pos   補充   toc   迴圈   技術   

【Java】 使用Java實現一則演算法前情提要

在學習Java的過程中,我的一個基友扔給了我一道演算法題,為了檢驗自己對Java的學習情況我決定使用Java解決這道演算法題。

具體問題

現有一株K叉樹,我們知道其前序走訪與後序遍曆,也知道K的值,求該K叉樹有多少種可能形態。如一13叉樹,前序走訪為abejkcfghid,後序遍曆為jkebfghicda,則其可能形態有207352860種。

問題分析

根據遍曆的定義我們可以知道:

  1. 前序走訪的第一個字母和後序遍曆的最後一個字母是他的根。

  2. 前序走訪的根的後一個字母是它最左邊的子樹。

  3. 後續遍曆的根的前一個字母是它最右邊的子樹。

以題目為例:(這裡我們從後序遍曆入手)

  1. a為該樹的根,d為a的最右子樹,其餘字母都是a的後裔;

  2. 以d為根,在前序走訪中d右邊的為d的後裔(無);d左邊的為d的兄弟及其後裔(即bejkcfghi),其中c為除了d外a的最右子樹。

  3. 以c為根,在前序走訪中c右邊的為c的後裔(即fghi), c左邊的為c左邊的兄弟及其後裔(即bejk),c的後裔的前序走訪為fghi,後序遍曆為fghi,i為c的最右子樹;c的左邊的兄弟及其後裔的前序走訪為bejk,後序遍曆為jkeb。b為除了d,c外a的最右子樹;

  4. 先處理c左邊的兄弟及其後裔,可知b為a的子樹,c、d的兄弟;e為b的子樹;j、k為e的子樹;

  5. 處理c的後裔,根據上述處理方法易得f、g、h、i都是c的子樹;

  • ,可見a有3個子樹,b有1個子樹,c有4個子樹,e有2個子樹。因為是13叉樹,當一個根節點有n個子樹,則該結點與子樹的排列可能性為C(n,13),故該13叉樹總的可能形態有C(3,13)* C(1,13)* C(4,13)* C(2,13) = 207352860。

  • 總結以上過程,我們需要的東西是一個能將K叉樹不斷拆分,能求出每一個根節點子樹數量的方法。

程式實現

首先,我們要明白我們需要什麼:

  1. 一個main類,裡面能初始化我們所需要的資料,包括題目給出的K,前序走訪和後序遍曆,最好還能最後處理結果並輸出。

  2. 在分析過程中我們需要用到大量的C(n,k),如果每個C(n,k)都單獨運算的話非常麻煩,我們可以用一個數組計算並儲存它們。

  3. 下面自然是重頭戲了,通過方法實現演算法。這個方法:

1.需要能根據給定的前序走訪和後序遍曆判定出根節點;

2.通過根節點拆分前序走訪和後序遍曆,同時計算每個根節點子樹的數量;

3.能夠調用自己,因為拆分自己是要不斷迴圈的,此外我們還需要一個數組用於記錄有多少個根,每個跟有多少個子樹,這個數組顯然是應該獨立在方法外的。

實際程式
public class qianhou {                         //主類  public static void main(String[] args){    String qian = "abejkcfghid";               //初始化輸入    String hou = "jkebfghicda";    byte k = 13;        long poss = 1;                             //結果    char [] dlr = qian.toCharArray();          //Java中對String類型利用複雜,轉化成char數組方便操作    char [] lrd = hou.toCharArray();           //dlr前序走訪,lrd後序遍曆    Jisuan a1 = new Jisuan();                     int[] zuh=a1.setarray(k);                  //將方法計算的組合數結果    a1.find(dlr,lrd);                           for (int i=1; i<a1.ccount+1; i++){         //計算結果        poss = poss * zuh[a1.acco[i]];    }    System.out.println(poss);  }} class Jisuan{    int[] acco = new int[10000];                   //建立數組記錄根節點子樹個數(也可以用ArrayList,雖然給ArrayList數組內的值++比較麻煩,但可以控制數組大小。注意不能寫在方法中    int ccount = 0;                            //acco數組指標    public int[] setarray(byte k){             //記錄C(n,k)值的數組        int[] zuhe = new int[k+1];        zuhe[0] = 1;        for (int i=1; i<=k; i++){              zuhe[i] = 1;              zuhe[i] =zuhe[i-1]*(k+1-i)/i;        }           return zuhe;    }       public void find(char[] dlr , char[] lrd){ //調用對象應為前序走訪與後序遍曆,因為有完整的資訊        int i1 = 0, i2=0, i3 = 0;              //初始化指標        int l = dlr.length;                    //初始化遍曆長度           while (dlr[i1] != lrd[l-1]){           //尋找前序走訪中的最右子樹位置          i1++;         }        //此處由於時間關係,未使用try校正初始條件是否合理,應該補充        if (l != 1){                           //如長度為1則無子樹,不需要繼續分割            if (i1!=0){                        //如果最右子樹在前序走訪中位置不為0,說明無左側兄弟及其後裔,左側無需分割                char[] ldlr = new char[i1];    //將左側兄弟及其後裔的前序走訪與後序遍曆分割分割                char[] llrd = new char[i1];                for (i2=0; i2<i1;i2++){                    ldlr[i2] = dlr[i2];                    llrd[i2] = lrd[i2];                }                acco[ccount] = acco[ccount]+1; //根下子樹數量+1                find(ldlr,llrd);               //先分割左側兄弟及其後裔,先遍曆根的所有兄弟,無需大量調控記錄數組的指標            }            if (i1!=l-1){                      //如果最右子樹在前序走訪中位置不為末尾,說明無後裔,右側無需分割                char[] rdlr = new char[l-i1-1];//將其後裔的前序走訪與後序遍曆分割分割                char[] rlrd = new char[l-i1-1];                for (i3=0; i3<l-i1-1;i3++){                    rdlr[i3] = dlr[i3+1+i1];                    rlrd[i3] = lrd[i3+i1];                }                ccount++;                      //數組指標指向下一個根                acco[ccount] = 1;              //根下子樹數量+1                find(rdlr,rlrd);            }        }    } }
總結

Java雖然並不適合用來寫演算法,但是就是因為這重重障礙和限制條件,寫起演算法來能遇到更多的問題,在解決這些問題的過程中,反而能更加深入的理解Java的內在邏輯和自身的缺陷。

  • 這大概就是所謂的時間是檢驗真理的唯一標準了吧...

使用Java實現一則演算法

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.