KMP及KMP改進演算法

2021-06-20 22:48:16 字數 1633 閱讀 6505

kmp」看毛片「演算法確實很難理解,上網搜了半天想了很久才大概想明白。kmp演算法精華在於next陣列:

"部分匹配值"即next陣列就是"字首"和"字尾"的最長的共有元素的長度。以"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。

有的人可能看過其他講解上next陣列有的為-1,其實這只是兩種表示方法的不同,大話資料結構上求得的next陣列資料是以0為開始的,也是以0為判斷,但是其next陣列中存的值為字首和字尾最長的共有長度加1,而待求陣列也都是資料從下標1開始,第零為儲存的為字串長度。而next陣列值為-1的講解則是字串陣列下標為0開始的:

例如: 大話資料結構中,使用了自定義的字串結構,t[0]為儲存模式匹配字串的長度,next[0]沒有用,next陣列和t陣列都是從下標1開始使用,即next[1]=0,t[1]為字串第乙個字元;而另外一種以正常字串儲存的,則是t[0]即為字串第乙個字元,next[0]=-1則是next陣列中第乙個值。

例如「aaab」   大話資料結構中儲存方法求得的next陣列為:next[0]=不使用,next[1]=0,next[2]=1,next[3]=2,next[4]=3,

而以正常字串儲存方法求得的next陣列為:next[0]=-1,next[1]=0,next[2]=1,next[3]=2,

用正常字串儲存方法求next陣列的**為:

void get_next(string t,int *next)

else

j=next[j];

}for(i=0;i

}對應的kmp演算法為:

int index_kmp(string s,string t,int pos)

else

}if(j>=lent)

return i-lent;

else

return -1;

}改進的kmp演算法:

kmp演算法對於如「aaab」這個字串,並不是最好的,比如去匹配」aaacaaaa「,在第四位c失配,kmp演算法會使j滑動到aaab,依然不匹配,則滑動到aaab,直到第一位。因此其實這幾 步是多餘的,當字首和字尾字母相同時,用之前的next值即可。

改進的求next陣列**:

void get_nextval(string t,int *next)

}else

j=next[j];

}for(i=0;i

}

改進的k m p演算法

前面的文章中講述k m p演算法的的基本實現,這裡提供 了改進後的k m p演算法的實現 手動驗算過,靠譜 相比於之前,就是在計算next值的同時多了一次比較,如果a位字元與它的next值指向的b位字元相等,則a位的nextva就指向b位的nextval,如果不相等,則該a位的nextval值就是它...

KMP詳細解釋及KMP演算法模板

kmp是什麼,kmp解決什麼型別的問題 kmp全稱為knuth morris pratt演算法,是一種高效的字串匹配演算法,尋找乙個字串中是否包含另乙個字串,例如 char s ababababcab char p ababc s為模板串 主串 p為子串,在s中找到p的位置 暴力匹配演算法 o n ...

kmp及擴充套件kmp

kmp匹配主要匹配的是兩個字串,我們將需要匹配的記錄為s1,用於匹配的串為s2.kmp匹配的是從以當前s1中的ch字元為末尾的字串能夠在s2中匹配的最大字首的長度。也即是s1中的每個字首的最長字尾所匹配的s2的最長字首。先考慮自身與自身匹配的情況 如果用dp 數學歸納來思考 假設當前需要匹配j位置的...