到東西,如下圖:
那這個演算法是怎麼實現的呢,用到了一種高階資料結構--字典樹,或者說是字典樹思想,因為字典樹不規定你具體怎麼實現,可以二維陣列,可以map
……也可以通常的結構體+next指標。可以通過乙個題來講述,就是2009acm/icpc 哈爾濱 reginal現場賽g題:fuzzy google suggest(
)講解。當時我搞這題,不知道字典樹,然後一直模擬,結果……(— —|||)先用輸入的單詞構造一棵字典樹,節點資料報括:cnt,表示節點上的字母被多少個單詞經過;vis,0表示經過此節點不能繼續匹配,1表示經過此節點可繼續匹配,2
表示此節點就是恰好用於匹配的字首的最後乙個字元;然後乙個next陣列,大小26,但不是node指標,而是int陣列,表示當前節點的兒子,next[i]==-1表示當前節點
沒有第i個兒子,否則有,並將此兒子結點進行編號,其編號就是它在字典樹中的編號。然後根據編輯距離進行dfs遍歷;函式設計為dfs(int x,int pos,int
edit,char* key),x是trie樹中第x個節點,pos表示匹配到了字首字元key的第pos個字元,edit表示剩餘可用的編輯距離。假如某個字元符合當前字首的匹配條件,則
trie節點向兒子結點遞迴,pos++,edit不變dfs(root[x].next[key[pos]-'a'],++pos,edit,key);否則嘗試使用編輯距離:1,增加乙個字元,此時要遍歷26個字元
,看增加哪個合法(即此字元在trie中出現了並且是當前key[pos]的兒子節點並且此字元不跟key[pos]相同),然後繼續dfs,此時編輯距離少乙個,key的位置不變,
trie走向兒子節點,假設增加的字元編號為i,則dfs(root[x].next[i],++pos,edit-1,key);2,替換乙個字元,此時edit減一,pos向前走乙個,dfs(root
[x].next[i],pos+1,edit-1,key);3,刪除乙個字元,刪除表示為trie節點不變,但是字首字串key串往下走乙個,相當於就沒匹配上的忽略,dfs(x,pos+1,edit-
1,key),若能遍歷下去,且x節點之前不可通行,則將x標記為可通行.到達匹配終點的條件有三個:1,字首串key一路匹配到了末尾,此時的結點x被標記為,root[x].vis=2,表示它是某個字首串的終結者。2,在tire中一路通行突然edit
用完透支了,那這個字首串沒有找到匹配的單詞,回溯。3,碰到了某個節點x,root[x].vis=2,說明到x這個字首串已經能夠匹配。返回可以匹配。然後再利用dfs_calc函式計數符合匹配的單詞數量:vis=2的結點。最後用dfs_clear()函式清理trie樹。關於銷毀trie樹,見有人用乙個for迴圈搞定的,那
樣只是把和根節點直接相連的結點進行了delete,但是其他的都變成懸空狀態,並未被銷毀。壞習慣(但對acm題來說不失為一種銷毀的捷徑)。不過用struct寫的交上
去老是re,極度掣肘,只好參看某牛的改作陣列實現的trie:
re的:
關於字串模糊匹配
一種比kmp和bm 更高效的匹配演算法 如果想看原英文介紹,看下面分割線後的 適用於 模式串較短的情況,最壞時間複雜性為o n m 不過一般沒這麼壞 sunday演算法其實思想跟bm演算法很相似,只不過sunday演算法是從前往後匹配,在匹配失敗時關注的是文字串中參加匹配的最末位字元的下一位字元。如...
字串匹配演算法 字串匹配演算法總覽
字串匹配在文字處理裡非常重要,我們採用簡潔的python 把以下演算法一一實現並講解。樸素演算法 algorithm rabin karp 演算法 有限自動機演算法 finite automation knuth morris pratt 演算法 kmp algorithm boyer moore ...
字串模糊匹配 根據萬用字元
在我們程式設計過程中,經常需要遇到字串和指定的模板匹配,需要返回是否匹配字串模板。其中符號 匹配任意多個位元組,匹配單個字元 模板形式舉例如下 1 010 010?用於判斷 號碼是否是010開頭。2 民主 用於判斷文字中是否含有敏感詞。3 銀行 信用卡 用於判斷文字中是否含有特殊的語義。我們需要用文...