詳解KMP算法以及python如何實(shí)現(xiàn)
算法思路
Knuth-Morris-Pratt(KMP)算法是解決字符串匹配問題的經(jīng)典算法,下面通過一個(gè)例子來演示一下:
給定字符串"BBC ABCDAB ABCDABCDABDE",檢查里面是否包含另一個(gè)字符串"ABCDABD"。
1.從頭開始依次匹配字符,如果不匹配就跳到下一個(gè)字符
2.直到發(fā)現(xiàn)匹配字符,然后經(jīng)過一個(gè)內(nèi)循環(huán)嚴(yán)查字符串是否匹配
3.發(fā)現(xiàn)最后一個(gè)D不匹配,下面就該思考應(yīng)該把字符串向右移動多少個(gè)位置呢?傳統(tǒng)做法可能是移動一格,KMP算法就創(chuàng)新在這里。KMP算法通過查詢一個(gè)Partial Match Table(表內(nèi)存有字符串信息),然后計(jì)算出需要移動的步數(shù),這個(gè)表后面會介紹怎么來的。
這里我們看到D前面是B,查表得到第二個(gè)B對應(yīng)的是2,所以 移動數(shù) = 已匹配字符數(shù) - 查表所得數(shù) 也就是 6 - 2 = 4, 需要向右移動四格。
下面也是重復(fù)這個(gè)步驟
直到發(fā)現(xiàn)匹配或者字符長度超出(未發(fā)現(xiàn)匹配)。
Partial Match Table
那么這個(gè)查詢的表是怎么來的呢?仍然以"ABCDABD"為例
- "A"的前綴和后綴都為空集,共有元素的長度為0;
- "AB"的前綴為[A],后綴為[B],共有元素的長度為0;
- "ABC"的前綴為[A, AB],后綴為[BC, C],共有元素的長度0;
- "ABCD"的前綴為[A, AB, ABC],后綴為[BCD, CD, D],共有元素的長度為0;
- "ABCDA"的前綴為[A, AB, ABC, ABCD],后綴為[BCDA, CDA, DA, A],共有元素為"A",長度為1;
- "ABCDAB"的前綴為[A, AB, ABC, ABCD, ABCDA],后綴為[BCDAB, CDAB, DAB, AB, B],共有元素為"AB",長度為2;
- "ABCDABD"的前綴為[A, AB, ABC, ABCD, ABCDA, ABCDAB],后綴為[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的長度為0。
python實(shí)現(xiàn)
def partial_table(p): '''''partial_table("ABCDABD") -> [0, 0, 0, 0, 1, 2, 0]''' prefix = set() res = [0] for i in range(1, len(p)): prefix.add(p[:i]) postfix = {p[j:i + 1] for j in range(1, i + 1)} #print(p[:i+1],prefix,postfix,prefix & postfix or {''}) res.append(len((prefix & postfix or {''}).pop())) return res def kmp_match(s, p): m = len(s); n = len(p) cur = 0 # 起始指針cur table = partial_table(p) while cur <= m - n: #只去匹配前m-n個(gè) for i in range(n): if s[i + cur] != p[i]: cur += max(i - table[i - 1], 1) # 有了部分匹配表,我們不只是單純的1位1位往右移,可以一次移動多位 break else: return True # loop從 break 中退出時(shí),else 部分不執(zhí)行。 return False print partial_table1("ABCDABD") print kmp_match("BBC ABCDAB ABCDABCDABDE", "ABCDABD")
以上就是詳解KMP算法以及python如何實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于python實(shí)現(xiàn)KMP算法的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python 循環(huán)while和for in簡單實(shí)例
下面小編就為大家?guī)硪黄猵ython 循環(huán)while和for in簡單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08Python實(shí)現(xiàn)bilibili時(shí)間長度查詢的示例代碼
這篇文章主要介紹了Python實(shí)現(xiàn)bilibili時(shí)間長度查詢的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01Pandas讀取excel合并單元格的正確方式(openpyxl合并單元格拆分并填充內(nèi)容)
Excel文件中可能包含合并單元格的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于Pandas讀取excel合并單元格的正確方式,主要介紹的openpyxl合并單元格拆分并填充內(nèi)容,需要的朋友可以參考下2023-06-06python?遠(yuǎn)程執(zhí)行命令的詳細(xì)代碼
有時(shí)會需要在遠(yuǎn)程的機(jī)器上執(zhí)行一個(gè)命令,并獲得其返回結(jié)果。對于這種情況,python 可以很容易的實(shí)現(xiàn)。今天通過實(shí)例代碼介紹下python?遠(yuǎn)程執(zhí)行命令的相關(guān)知識,感興趣的朋友一起看看吧2022-02-02Python和Anaconda的版本對應(yīng)關(guān)系
這篇文章主要為大家介紹了Python和Anaconda,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06Pandas常用的讀取和保存數(shù)據(jù)的函數(shù)使用(csv,mysql,json,excel)
本文主要介紹了Pandas常用的讀取和保存數(shù)據(jù)的函數(shù)使用,主要包括csv,mysql,json,excel這幾種方式,具有一定的參考價(jià)值,感興趣的可以了解一下2022-01-01