題目:有乙個江洋大盜,他每次寫信都是從一張報紙上剪下單詞,再把單詞貼在信上。假如某張報紙的單詞儲存在vector***** 中,而信的單詞儲存在vectorletter 中,寫乙個演算法程式判別該報紙可不可以生成該信?
對比一些方法: 這裡假設*****:(m個單詞,每個單詞平均d個字母),letter:(n個單詞,每個單詞平均d個字母)。對於中文詞語而言,一般2~4個字左右,對於英文單詞,d就要大一點,但基本上也是常數。因此d遠遠小於m,下面比較的時候就不考慮單詞中每個字元間的比較了。
(1) 蠻力匹配:
把n中每個單詞與m中的每個單詞一一比較。時間複雜度為:o(m*n)。估計誰也不會選這種。
(2) 二分查詢:要求,對*****建有序索引。
*****排序的時間複雜度最好為o(m*logm)。
對letter中的所有單詞二分查詢的時間複雜度為o(n*logm)
總的時間複雜度為o((m+n)*logm). 比蠻力查詢效率要好不少。
缺點:如果換了新報紙,所有的單詞都必須重新排序,需要o(m*logm)的時間來建立索引。
(3) trie樹: 要求,對*****建trie索引樹
*****建立trie樹的時間複雜度為o(m)。
對letter中所有單詞在trie樹中查詢的時間複雜度為o(n).
總的時間複雜度為o(m+n)。效率絕對要比二分查詢好。
優勢: 如果換了新報紙,重新建立一顆trie樹的時間o(m)也小於二分查詢建立有序索引的時間o(m*logm)要小的多。
缺點:建立trie樹所需要的空間代價是很大的。如果是中文詞語的trie樹,那麼放進全部載入進記憶體是很可怕的,需要把trie樹用b樹的方法儲存在磁碟上。詳見:《trie樹 》
(4) hash表: 要求,對*****建立hash結構
建立hash表結構的時間複雜度為o(m),注意需要計算每個單詞的hashcode的時候,很可能要遍歷單詞中的每個字母。
對letter中所有單詞在hash結構中查詢的時間複雜度為o(n)。當然,這是在沒有任何雜湊衝突的理想情況下。選擇好hashcode的計算方式和雜湊表的大小,可以將衝突降到很低。因此我們這裡不考慮衝突。
總的時間複雜度為o(m+n)。由此可見,hash表結構與trie樹的效率都是相當的客觀。
缺點:如果換報紙。為了考慮衝突的可能性,hash結構的大小可能需要重新考慮。這一點很麻煩。當然,儲存空間上應該會比trie要好一些,但實際應用上並不比trie方便。
(5) 歸併查詢:要求,對letter和*****都建立有序索引。
對letter和*****排序的時間複雜度分別為o(m*logm)和o(n*logn)
歸併查詢的時間複雜度為o(m+n)
總的時間複雜度為o(m*logm+n*logn+m+n)
總結:對於這幾種方法而言,我更加青睞於trie樹。因為我相信報紙中的單詞數量基本上是保持穩定的,不可能達到海量級別。trie樹的空間代價其實並不算什麼。
preg match正則匹配的字串長度問題
專案中,用preg match正則提取目標內容,死活有問題,測得死去活來。後來懷疑php 的preg match有字串長度限制,果然,發現 pcre.backtrack limit 的值預設只設了100000。解決辦法 ini set pcre.backtrack limit 999999999 注...
關於python轉義字元在正則匹配中的問題研究
首先看乙個問題 import re text r 學 print text zz r 學 result re.findall zz,text print result 輸出 學 學 為什麼沒有匹配到反斜槓?轉義 首先要理解乙個概念,python中內建的語法字元竄中有一些特殊的符號,那就是 被成為轉義...
lua正則匹配中文 Lua的字串匹配與正規表示式
lua的字串匹配與正規表示式 使用lua一段時間了,簡單總結下string庫中的幾個與正則相關的函式。這些函式是find,match,gmatch和gsub。然後是lua中支援的正則。文中的例子在lua5.3的命令列中試驗過。5.1版的需要在提示符前加乙個 號或加return空格。string.fi...