KMP 模板
問(wèn)題
a : abbaabbaaba
b : abbaaba
求字符串a(chǎn)中一共有幾個(gè)b字符串
思路
- 復(fù)雜度O( n * m)常規(guī)的思路是從a的第一位開(kāi)始和b進(jìn)行比較,如果碰到一個(gè)字母不同,說(shuō)明從a的第一個(gè)開(kāi)始不能成功匹配。于是就從a的第二個(gè)字母與b相比較。
- 復(fù)雜度O( n * m)在方法一的基礎(chǔ)上,發(fā)現(xiàn)一個(gè)字母不匹配的話,如果a不回到第二個(gè)開(kāi)始的話,這樣復(fù)雜的降了很多。
如果a不回退,b就要回退。而且b回退的越少越好。
就例子而言:
a : abbaabbaaba
b : abbaaba
(下標(biāo)從0開(kāi)始)
當(dāng)匹配到最后一個(gè)字母發(fā)現(xiàn)不同(a[6] != b[6] 即 b != a),這時(shí)候讓a[6]和b[2]開(kāi)始匹配。完美!
問(wèn)題是你怎么知道是b[2]呢?這涉及到字符串的前后綴問(wèn)題,也就是求解next數(shù)組
KMP模板
struct KMP{ // 下標(biāo)0int nex[maxn];void get_nex(char *buf, int len) {nex[0] = -1;int i = 0, j = -1;while (i < len) {if (j == -1 || buf[i] == buf[j]) nex[++i] = ++j;else j = nex[j];}}int get_kmp(char *buf1, char *buf2) { // buf1匹配串,buf2模式串int len1 = strlen(buf1), len2 = strlen(buf2);get_nex(buf2, len2);int cnt = 0, i = 0, j = 0;while (i < len1) {if (j == -1 || buf1[i] == buf2[i]) ++i, ++j;else j = nex[j];if (j == len2) cnt++, j = nex[j];}return cnt; // 匹配個(gè)數(shù)}// (len - nex[len]) 最小循環(huán)節(jié),前提len % (len - nex[len]) = 0 }kmp;總結(jié)
- 上一篇: 浩然GG和女朋友的游戏 (数学,规律)
- 下一篇: 2264: sequence(KMP)