總結: 這兩週幹了什麼

1. Programming Pearls
2. Dynamic programing, Greedy algorithm
3. 排列, 組合
4. 設計模式
5. 讀書列表
6. 接下來幹什麼


這兩週都在看技術上的書, 所以記在這裏。

1. Programming Pearls

<Programming Pearls>, 每天看一篇, 現在已經看了10篇了, 第一部分應該是提綱挈領的說, 使我對軟件工程的工程這個概念有了進一步的認識, 我抄下了認爲精彩的一段:

Roebling was a good engineer, and he built a good bridge by employing a huge safety factor to compensae for his ignorance(No ignorance, this is engineering).

We would design the way Jonh Roebling did, and not the way his contempararies did. So far as I know, none of the suspension bridges built by Roebling j's contempararies in the U.S still stands, and a quarter of all the bridges of any type built in the U.S in the 1870's collapsed within then years of their construction.

人生又何嘗不是這樣。

具體來說, 第一部分以排序爲切入點, 講到一個具體程序的問題分析, 算法, 數據結構, 程序驗證, 調試, 編碼, 到程序的優化。 給人的很多觀念上的啓發。 如果說我還記得什麼的話, 我能想到這麼一些關鍵字: don't rush into your first idea, bit map, hash map, approximate calculation, quick calculation, common sense, easy judgement, "everything should be made as simple as possible(Einstein)"

Binary search 的例子讓人都不敢相信:
"A binary search is a notoriously tricky algorithm to program correctly. It took seventeen years after its invention until the first correct version of a binary search was published"

要認真啊。

2. Dynamic programing, Greedy algorithm
<the algorithm design manual>, <introduction to algorithms>兩本一起, 回顧算法上的一些東西, 主要集中在Dynamic programming, greedy programming, tree上面. 看過線性代數以後, 終於明白了greedy algorithm的matroid. 我覺得DP, GP的關鍵就在那個optimal structure上面, 能實現問題的分治。Again, Don't rush into your first idea!Huffman 編碼是GP的一個例子, 但是Huffman編碼不能用那個matroid理論說明, 因爲, 編碼間並不是子問題的關係, 我覺得Huffman編碼只是有那個Greedy的概念。


3. 排列, 組合
然後就是排列, 組合問題, 最直接的辦法就是遞歸了。但學到了一個更高明的辦法, 就是對所要表達的排列/組合編碼, 比如, 生成{1,2,3}的所有子集: 把1,2,3分別用一個比特位表示,當一個數出現在一個子集中的時候, 對應的比特位就是0, 否則是1。 設定a, b, c 分別表示1,2,3, 二進制數abc就可以表示2^3種集合了(包括空集), 下面是一段java代碼:

 /*
   *  @param n, the size of the base set
     */
   public void encodedPerm(int n){
        //the number of the subsets
        int setNum = (int)Math.pow(2, n);
        int[] key = new int[n];
        int op = -1;
       
        //generate the base set and the key lookup table
        HashMap<Integer, String> baseSet = new HashMap<Integer, String>();
        baseSet.put(Integer.valueOf(0), "");
        for(int i = 1; i <= n; i++){
            key[i-1] = (int)Math.pow(2, i-1);
            baseSet.put(Integer.valueOf(key[i-1]), Integer.toString(i));
        }
       
        for (int i = 0; i < setNum ; i++){
            System.out.print("code "+i+" : ");
            //generate a subset by examing bit by bit
            for(int j = 0; j < n; j++){   
                op = key[j] & i;
                System.out.print(baseSet.get(Integer.valueOf(op))+"/t");
                //System.out.print(op);
            }
            System.out.println();
        }
    }

還有一個辦法就是, 做遞歸處理, 每次增加一個元素, 假設給定的集合是一個數組, 那麼新一輪增加的元素序號必須比上一輪大。 比如, 集合int[] A = {3,7,5}; 當空集新增了3(元素序號0)以後, 下輪可以增加7(元素序號1); 但空集新增7以後, 下一輪不能增加3

base set A as a global value
D is initialized to -1

fun(sub set B, last index D){

if(D equals to A's length - 1)   
     return
for each element Elem with index > D in the set A
     expand subset B by the A[D]
     do anything you want with the subset
     D = Elem's index
     fun(A, D)
}

如果沒有序號上的限制, 就可以做排列了。 說到排列, 也是可以編碼的, 但是稍微複雜一些的編碼。有些問題還沒有弄明白, 再看看。

4. 設計模式

在圖書館沒有找到傳說中的經典, GoF, Head First。 開始看的是<design patterns in java>, 挺爛的書, 還不如維基百科講的明白。 後來找到<design patterns explained>,好一些, 問題都講清楚了。

經典的設計模式都過了一遍, 不敢說都記得, 但提到一個具體的模式我應該知道了。 這方面, 以後要積累的。

5. 讀書列表

收集了一個40項的讀書列表, 都是從看過的書裏面摘錄下來的書, 有機會可以再看。

6. 接下來幹什麼

我打算下週就要具體的練習一下編程了。TopCoder或者其他的題目。不然都生疏了。然後再做分形, 想了很久很久了。

還有就是Set partition 的編碼問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章