b99902HW 板


LINE

因為好像很多人還是不太懂,所以就嘗試PO篇文解釋一下KMP~~ 如果有哪裡寫錯煩請告知>w< --- 為了方便說明我先定義一些符號: 字串(string) 一個字串S = a_1 a_2 a_3 … a_n 是一個字母組成的sequence(序列) 其中定義S[1] = a_1, S[2] = a_2, ... S[i] = a_i. 子字串(substring) S[i:j]就表示 a_i a_i+1 … a_j-1 a_j //假設i<=j 我們稱S[i:j]為S的子字串,當然特別有S = S[1:n]。 EX: aaaab 就是 aaaaaabbb 的一個子字串 前綴(prefix) 一個字串是長這樣子的話S = |--------------| 那 S'= |------| S'就是S的一個prefix 嚴格來說如果一個字串是S = S[1:n] 那 S'= S[1:i] 當i<=n時,S;就是S的一個prefix EX: a,ab,abc,abcd,abcde,abcdef 都是 abcdef 的前綴。 F函數 從字串S中的i位置往前延伸,最多可以往前幾位(< i) 使得往前的這個位數是S的前綴。 嗯看起來非常繞口的一句話= =... 從數學上來看就是最大的滿足S[i‐F(i)+1:i] = S[1:F(i)]的數 且 F(i)<i 不過如果不存在F(i) 就假設他 = 0吧~ 想必還是不懂所以就舉個例子吧: 1 2 3 4 5 6 7 8 9 (index) S = a b a b a a b a b 0 0 1 2 3 1 2 3 4 (F函數) 如果還是不懂 就我們一個一個來看@_@ F(1) = 0 因為 a babaabab ababaabab F(2) = 0 因為 ab abaabab ababaabab F(3) = 1 因為 aba baabab a babaabab F(4) = 2 因為 abab aabab ab abaabab F(5) = 3 因為 ababa abab aba baabab 注意!雖然有 a babaabab 這樣子也可以match 但是不是最長前綴 F(6) = 1 因為 ababaa bab a babaabab F(7) = 2 因為 ababaab ab ab abaabab F(8) = 3 因為 ababaaba b aba baabab a babaabab 也是但是不是最長 F(9) = 4 因為 ababaabab abab aabab ab abaabab 也是但是不是最長 看了一堆例子之後想必對F函數有點感覺了吧= =+ 而這個F函數其實就是KMP的精隨!! 假設上面例子:如果 上面叫實體字串 下面叫虛擬字串 那當我們在配對實體字串的時候 同時也在配對虛擬字串!! 意思就是我們在配對S[1:i]的時候 同時也配對了S[1:F(i)] 遞迴的來說 我們也同時配對了S[1:F(F(i))]也配對了S[1:F(F(...F(i)...))] (假設後面那項都>0的話) 就像F(9)在配對S[1:9]時 同時也配對S[1:F(9)] = S[1:4] 同時也配對S[1:F(F(9))] = S[1:F(4)] = S[1:2] !! 有沒有清楚明白XD!? 好我假設有:p 那你可能會想 這個F函數有什麼鳥用呢= =? 就像老師上課說的因為當你把S跟T配對(T是pattern)時, 如果在某個時刻已經配對到"S中的i"跟"T中的j"也就是S[i-j+1:i] = T[1:j] 下一個要比對的就是S[i+1]跟T[j+1]是否相等? 如果相等的話很好i++, j++。 如果不相等呢? 因為我們已經有T[1:j]的資訊了,所以不用再重新跑一次! 因為我們知道S[i-j+1:i] = T[1:j] S[i-F(j)+1:i] = T[1:F(j)] S[i-F(F(j))+1:i] = T[1:F(F(j))] S[i-F(F(..j..))+1:i] = T[1:F(F(..j..))] 所以我們可以直接把j變成F(j) 也就是比較S[i+1] T[F(j)+1]是不是相等? 如果相等的話很好i++, j=F(j)+1。(如果先做了j=F(j)那就只要j++就好了) 如果不相等呢? 這樣的情況跟上面最一開始的情況一樣了!! 總之就是一直做下去直到存在某個S[i+1] = T[F(F(..F(j)..))+1] 覺得符號很多頭昏眼花? 沒關係,讓我們來舉個例子。 0 1 2 1234567890123456789012 假設S = shikisfatabababahahaha T = abababab 00123456 (T的F函式的值) 假設現在match情況是這樣 shikisfatababab ahahaha S[10:15] = ababab ab T[1:6] 其中i=15, j=6。 則繼續往下比對之後會變成shikisfatabababa hahaha S[10:16] = abababa b T[1:7] 其中i=16, j=7。 (因為S[16]==T[7]所以只要i++,j++就好了) 然後繼續往下比對 shikisfatabababa hahaha S[10:16] abababa b T[1:7] 但是因為S[17]!=T[8] 即'h'!='b'所以會變成 shikisfatabababa hahaha S[12:16] ababa bab T[1:F(7)] = T[1:5] 但是因為S[17]!=T[6] 所以變成 shikisfatabababa hahaha S[14:16] aba babab T[1:F(5)] = T[1:3] 但是因為S[17]!=T[4] 所以變成 shikisfatabababa hahaha S[16:16] a bababab T[1:F(3)] = T[1:1] 但是因為S[17]!=T[2] 所以變成 shikisfatabababa hahaha S[17:16] abababab T[1:F(1)] = T[1:0] 有沒有點fu要怎麼用F來做比對了呢XDD? 那現在問題轉一下變成了 要如何求出F呢@@!? 我們可以利用一種類似遞推的方式 明顯的F(1) = 0 假設我們已經知道F(2) F(3) ... F(i-1) 那要怎麼求出F(i)呢? 其實仔細想一下的話 就會發現求出F的過程就ST匹配方式一樣哇!! 只是會變成T跟T自己做匹配而已:p 假設T = ababaabab 那麼一開始的話是 T = a babaabab i = 1 ababaabab j = 0 因為T[i+1]!=T[j+1] 且 j=0 所以F(2) = 0 T = ab abaabab i = 2 ababaabab j = 0 因為T[i+1]==T[j+1] 所以F(3) = j+1 = 1 T = aba baabab i = 3 a babaabab j = 1 因為T[i+1]==T[j+1] 所以F(4) = j+1 = 2 T = abab aabab i = 4 ab abaabab j = 2 因為T[i+1]==T[j+1] 所以F(5) = j+1 = 3 T = ababa abab i = 5 aba baabab j = 3 不合,故j=F(j) T = ababa abab i = 5 a babaabab j = 1 不合,故j=F(j) T = ababa abab i = 5 ababaabab j = 0 因為T[i+1]==T[j+1] 所以F(6) = j+1 = 1 T = ababaa bab a babaabab 因為T[i+1]==T[j+1] 所以F(7) = j+1 = 2 T = ababaab ab ab abaabab 因為T[i+1]==T[j+1] 所以F(8) = j+1 = 3 T = ababaaba b aba baabab 因為T[i+1]==T[j+1] 所以F(9) = j+1 = 4 T = ababaabab abab aabab 結束>w< ~~~~ 因此就得到F函數的值了>w< 呀乎\(^o^)/ 會求F函數的值也就同時會String Matching了!!! 不知道大家懂了沒=口=a 總之概念大概就這樣囉~~實踐方面就要自己動腦了XD" --- 不懂的還有不懂的話,這裡有我之前寫字串相關演算法的講義....雖然寫很爛啦= =||| http://w.csie.org/~b99902112/NTUcourse/Chapter8-String.pdf 不然就再說吧XD" 看是問老師問助教還是....喵:p --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 140.112.30.140
1F:推 gary810410:看懂了 感謝 03/22 20:41
2F:推 shik:真不想推...||| 03/22 20:43
3F:推 fei6409:胖胖郭超強的>w< 03/22 20:47
4F:推 skyly:一年多過去了...說好的精美圖片呢... 怎麼還是手寫的 XDDD 03/22 21:11
5F:推 poloo5582:我覺得一開始就教這個太超過了www 03/23 01:09
※ 編輯: math120908 來自: 118.160.236.217 (03/23 01:10)
6F:推 OppOops:必推 03/23 01:31
7F:推 garychou:大概懂了 不過shik被偷表還真可憐XD 03/23 03:41
8F:推 garychou:借轉到我的個版3Q 03/23 03:54
9F:推 mars90226:推~ 超強~ 03/23 13:07
10F:推 williamiced:推!不過我還是覺得好難QQ 03/24 14:13
11F:推 ga800360:快推不然人家以為我看得懂... 03/25 16:32
12F:推 q22554647:不能再同意樓上更多了QQ 03/25 20:55
13F:推 yesjimmy62:推小小郭啦~~~ 04/23 21:04
14F:→ math120908:樓上電機卷哥!! 04/23 23:48
15F:推 skyly:樓上上 soccer boy!! 04/25 23:00
16F:推 chickending:大大講解得真好!!!天降甘霖啊~~~~ 05/15 00:27







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Tech_Job站內搜尋

TOP