KMP算法又复习了一遍,写个总结,贴下自己的代码。
KMP算法介绍和原理
简单说就是字符串匹配,在主串中匹配模式串,返回匹配到的下标。
具体的可以看详解KMP算法这篇博客,讲的挺好的,也有图解。
这里只放几张截图,不做详细介绍了。


!["next[j]=k,表示当T[i] != P[j]时,j指针的下一个位置"](https://cdn.jsdelivr.net/gh/HanielF/ImageRepo@main/blog/kmp-3.png)

!["P[k]=P[j]时,next[j+1]==next[j]+1"](https://cdn.jsdelivr.net/gh/HanielF/ImageRepo@main/blog/kmp-5.png)
!["P[k] != P[j]时, k = next[k]"](https://cdn.jsdelivr.net/gh/HanielF/ImageRepo@main/blog/kmp-6.png)

KMP算法实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| i#include <cstring> #include <iostream> #include <string> #include <vector> using namespace std;
const long long int SIZE = 1e5; int myNext[SIZE];
void getNext(string p) { memset(myNext, -1, sizeof(myNext)); int j = 0; int k = -1; while (j < p.length() - 1) { if (k == -1 || p[j] == p[k]) { if (p[++j] == p[++k]) { myNext[j] = myNext[k]; } else { myNext[j] = k; } } else { k = myNext[k]; } } }
int KMP(string ts, string ps) { int i = 0; int j = 0;
int tsLen = ts.length(), psLen = ps.length(); if (tsLen == 0 && psLen == 0) return 0; if (tsLen == 0) return -1; if (psLen == 0) return 0; getNext(ps);
while (i < tsLen && j < psLen) { if (j == -1 || ts[i] == ps[j]) { i++; j++; } else { j = myNext[j]; } }
if (j == ps.length()) { return i - j; } else { return -1; } }
int main() { string t = "hello"; string p = "ll"; cout << KMP(t, p) << endl; return 0; }
|