恢復BLOG

好久沒寫了,學的東西不記錄下,複習都沒地方。算法好久沒系統的看看了,以前讀書的時候,每個書上的算法都自己在電腦上實現並測試通過,現在就是照着書估計也得花點時間才能實現一個簡單的排序算法了,悲劇。還得好好向德文同學學習啊,該同學在航信的時候就認真刻苦,現在跑到成都去養老了,不錯。

 

假設這有一個各種字母組成的字符串(長度M),假設這還有另外一個字符串(長度N),而且這個字符串裏的字母數相對少一些。從算法是講,什麼方法能最快的查出所有小字符串裏的字母在大字符串裏都有?

比如,如果是下面兩個字符串:

String 1: ABCDEFGHLMNOPQRS

String 2: DCGSRQPOM

答案是true,所有在string2裏的字母string1也都有。如果是下面兩個字符串:

String 1: ABCDEFGHLMNOPQRS

String 2: DCGSRQPOZ

答案是false,因爲第二個字符串裏的Z字母不在第一個字符串裏。

對於這種操作一種幼稚的做法是輪詢第二個字符串裏的每個字母,看它是否同在第一個字符串裏。從算法上講,這需要O(N*M)次操作。
一個稍微好一點的方案是先對這兩個字符串的字母進行排序,然後同時對兩個字串依次輪詢。兩個字串的排序需要(常規情況) O(MlogM)+O(NlogN)次操作,之後的線性掃描需要O(M+N)次操作。
再好點的算法就是對第一個字串進行輪詢,把其中的每個字母都放入一個Hashtable裏(成本是O(M))。然後輪詢第二個字串,在Hashtable裏查詢每個字母,看能否找到。如果找不到,說明沒有匹配成功。算法複雜度爲O(M+N)

上面是一般人都想得出的解決辦法,比如我們算法界的巨擘德文文同學,更是直接就提出最優解決辦法。我承認,我也只能想出這幾種辦法。但是。。。但是。。。有人(Guy)提出了一種新穎的解決該問題的辦法。該辦法如下:
假設我們有一個一定個數的字母組成字串 —— 我給每個字母分配一個素數,從2開始,往後類推。這樣A將會是2,B將會是3,C將會是5,等等。現在我遍歷第一個字串,把每個字母代表的素數相乘。你最終會得到一個很大的整數,對吧?然後 —— 輪詢第二個字符串,用每個字母除它。如果除的結果有餘數,這說明有不匹配的字母。如果整個過程中沒有餘數,你應該知道它是第一個字串恰好的子集了。這樣不行嗎?

現在我想告訴你 —— Guy的方案(不消說,我並不認爲Guy是第一個想出這招的人)在算法上並不能說就比我的好。而且在實際操作中,你很可能仍會使用我的方案,因爲它更通用,無需跟麻煩的大型數字打交道。但從”巧妙水平“上講,Guy提供的是一種更、更、更有趣的方案。

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