390 likes | 522 Views
字串演算法 String Algorithms. 本次大綱 1 - 一些基本的字串演算法符號名詞介紹 2 - Rabin Karp 簡介 3 - 自動機的演算法簡介 4 - KMP 演算法本體介紹 5 - 嗚喔 好題目. 符號. Σ 組成字串的字元集合 | Σ | 組成字串的字元集合大小 Σ* 由 Σ 所組成的所有 ” 有限長度 ” 的字串 ε 空字串 屬於 Σ*. 名詞. Prefix 一字串的前置 譬如字串 abcccd abc 是他的前置 ab 也是他的前置 也是 abc 的前置 Suffix 譬如字串 abcccd
E N D
字串演算法 String Algorithms • 本次大綱 • 1- 一些基本的字串演算法符號名詞介紹 • 2-Rabin Karp簡介 • 3- 自動機的演算法簡介 • 4-KMP演算法本體介紹 • 5- 嗚喔 好題目
符號 • Σ 組成字串的字元集合 • |Σ|組成字串的字元集合大小 • Σ* 由Σ所組成的所有”有限長度”的字串 • ε 空字串 屬於Σ*
名詞 • Prefix 一字串的前置 譬如字串abcccd abc是他的前置 ab也是他的前置 也是abc的前置 • Suffix 譬如字串abcccd cccd是他的前置 ccd也是他的前置 也是cccd的前置
Rabin Karp Algorithms • 想法核心:把一個字串看成數字 • 若一個字串abcdabc • 想法:視為1234123 • 先不考慮一個字串是否會overflow • 把字串”轉換成”數字去做比對
Rabin Karp Algorithms • 實作想法:用一個Table去實現一個字元的Mapping • Ex: abcdabcd • →a對應到1, b對應到2, c對應到3, d對應到4 • 所以一個|Σ|為N的字串 • 表示成N進位的數字
Rabin Karp Algorithms • 波動拳 ↓ → +A
Rabin Karp Algorithms • 昇龍拳 →↓ → +A
Rabin Karp Algorithms • 這是我自己”實作”的應用 • 如果遊戲你用字串比對是用迴圈去比對招數表,同時間需要的次數一多可能就會慢 • 如此就可能會發生…
Rabin Karp Algorithms • 實作上,Rabin Karp對於一個產生數字不大(在INT或LONGLONG) 的字串集合 有相當大的優勢 (譬如遊戲招數) • 所以問題應該經由分析之後,才確認採用何種演算法,並不是某一種演算法都一定比較快
Rabin Karp Algorithms • 最後實作細節: • 你可能發現升龍拳跟波動拳字串不一樣長了 • 假設你現在得到數字x • 比對波動拳用(x)%(N)^3 (有三個按鍵要比對) • 升龍拳用(x)%(N)^4(有四個按鍵要比對) • 其他相關的細節問題 也可以用modulus來解決
String Matching With finte automata • 想法核心:想成一個自動機的狀態轉移 • 初始狀況為q0 • 所有狀況為Q這個集合 • 當在一狀況q下 遇到字元alpha • 那麼下一個狀態會依循著這新的指令轉移
String Matching With finte automata • 如果將狀態看成一個數字 其實就跟Rabin Karp很類似了 假設目前狀態是15456,得到新的字元g,他代表7這個數字,那新的狀態就是154567 • 那字串比對的目標就是一個FinalState • 假設自動機到了最終狀態 那代表已經讀到了一個要尋找的字串 • 本篇將不再多在此處著墨,有興趣的人可以閱讀Introduction to algorithms 2/e的page916 – page 922
KMPAlgorithms • 核心觀念:將之前比對過的資料充分利用 • 實作資訊: • Si代表一字串從S[0]…S[i] • failure function definition : failure[i]代表最長Si的prefix與他自己的suffix相符是多少 而failure[i] < i (注意這個限制!)
KMPAlgorithms • fail function diagram(圖例) • Ex: Sq = abcwerabc • 則failure[q] = ? • 以本例的話 failure[q] = 2 • 因為Sq的prefix最長S2與後面Sq的suffix相等 • 雖然S1也符合 但是S2才是最長的
KMPAlgorithms • How to use failure function • 主要字串 • 比對字串 • 當比對出錯誤時,我們可以怎麼省工夫? • 這兩段相同 • 你會發現這段字串 • 跟綠色字串的關係 (繼續...)
KMPAlgorithms • 目前的狀況 • T’’ = • Sub’ = • 有多少已經比對過? • 我們會想知道Sub”已經知道”的Prefix最長可以跟T’的Suffix相同的 是到哪邊
KMPAlgorithms • 新的比對的狀況 • 我們知道因為上下兩個子字串完全相等 • 那這三格是”最長”的prefixof T’’等於suffix of Sub’ • 因此就不會有”更好”的”省略比對”選擇了
KMPAlgorithms • 新的比對的狀況 • 省略不必要的比對 • 我們就拿Sub第四個元素重新與T第十個元素比對 • 你會發現找這個最長的prefix步驟其實就是 • 假設比對到Sub[j]不符合的時候 • 就可以直接省略比對failure[j]個字元 並”重新比對一次”該字元
KMPAlgorithms • 萬一又不符合 就不斷重複這樣的步驟 • 一樣省略不必要的比對 採用策略一樣是尋找最長的prefix與suffix相等的情況 • 我們就拿Sub第二個元素重新與T第十個元素比對 • 這樣的步驟將持續到 j = -1或者Sub[j] 跟 T[i]相等
KMPAlgorithms • 狀態的轉移 • 其實這樣的步驟 就是在使得狀態轉移 • 轉移的是j,這樣的動作就像自動機一樣 • 當你比對到新的字元 • 你一定會進入新的狀態 => 比對成功 或者j = failure[j] 這樣來省略比對步驟
KMPAlgorithms • 程式碼實現=> • Part 1 計算目標字串自己的prefix跟suffix的關係 (Failure function) • Part 2 利用Failure function去比對需要比對的字串
KMPAlgorithms • Failure Function的實現 • 其實作法跟有Failure Function時與主字串比對的動作類似 • 假設已經知道之前的Failure Function • 那目前的比對可能會產生兩種結果
KMPAlgorithms • Failure Function的實現 • 1.成功比對 存入Failure Function
KMPAlgorithms • Failure Function的實現 • 2.比對失敗 進行j的狀態轉移,一樣利用之前已經比對過的結果,節省要比對的次數
KMPAlgorithms • Failure Function的小要點 • 依照原本定義,圖片中藍色的段落是可以重疊(過半)的,不要被圖片迷惑
KMPAlgorithms • 程式碼 (fail function) fail[0] = -1; for(inti = 1, j = -1; i < Sub.size(); i++) { while(j >= 0 && Sub[i] != Sub[j+1]) j = failure[j]; //避免重複比對 if(Sub[i] == Sub[j+1]) j++; //比對成功 failure[i] = j; //紀錄failure function }
KMPAlgorithms • 程式碼 (String matching KMP) for(inti = 0, j = -1; i < T.size(); i++) { while(j >= 0 && T[i] != Sub[j+1]) j = failure[j]; //避免重複比對 if(T[i] == Sub[j+1]) j++; //比對成功 if(j == S.size()-1) //找到了目標字串 { cnt++; //找到了一次 j = failure[j];} }
好題目 • 題目大意: • 給定一字串S,試求最少需要加入幾個字元在該字串後面,使該字串成為一個回文(palindrome) • 譬如說abcba是一個回文 而abcb則不是
好題目 • 出處 ACM UVA Contest Problem Set 11475 – • Extend to Palindrome • 網址http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=26&page=show_problem&problem=2470
好題目 • 參考解答: • 設原本字串為S,一反轉字串為S’ • 則我們想要知道的是 • S’字串 的prefix可以跟S的suffix相符合到多長 • 這樣一個看似無從下手的問題,就正好是一個字串比對了,其中可以用KMP來實現加速
好題目 • 程式參考解答 個人網誌網址: • http://robertanders.pixnet.net/blog/post/27122820
建議閱讀 • Introductions to algorithms 2/e page.907 • page.932 (如果自己覺得自習可以的話)