Skip to content
Ficon's Paper
Go back

String

Table of contents

Open Table of contents

KMP

int kmp(string& s1, string& s2) {
  int n = s1.length();
  vector<int> pi(n);
  for (int i = 1, j = 0; i < n / 2; i++) {
    while (j && s2[i] != s2[j]) j = pi[j - 1];
    if (s2[i] == s2[j]) j++;
    pi[i] = j;
  }
  for (int i = 0, j = 0; i < n; i++) {
    while (j && s1[i] != s2[j]) j = pi[j - 1];
    if (s1[i] == s2[j]) j++;
    if (j == (int)s2.length()) {
      return i - j + 1;
    }
  }
  return -1;
}

定义 pi[i]s[0, i] 的前缀与后缀相等的最大值(前缀和后缀不能等于字符串本身)

i 代表已经匹配的后缀的下一位,j 是已经匹配的长度,[0, j - 1][i - j - 1, i - 1] 已经匹配完成,比较下一位 s[i] 是否等于 s[j],如果相等,则 i++, j++,否则就在 [0, j - 1] 中寻找可以复用的前缀,即 j = pi[j - 1],因为 pi 存的是匹配的长度,所以将它赋值给 j 恰好就是 [0, pi[j - 1] - 1] 的下一位。


Share this post on:

Previous Post
Graph Theory
Next Post
Data Structure