kmp」看毛片「演算法確實很難理解,上網搜了半天想了很久才大概想明白。kmp演算法精華在於next陣列:
"部分匹配值"即next陣列就是"字首"和"字尾"的最長的共有元素的長度。以"abcdabd"為例,
- "a"的字首和字尾都為空集,共有元素的長度為0;有的人可能看過其他講解上next陣列有的為-1,其實這只是兩種表示方法的不同,大話資料結構上求得的next陣列資料是以0為開始的,也是以0為判斷,但是其next陣列中存的值為字首和字尾最長的共有長度加1,而待求陣列也都是資料從下標1開始,第零為儲存的為字串長度。而next陣列值為-1的講解則是字串陣列下標為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。
例如: 大話資料結構中,使用了自定義的字串結構,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位置的...