标签:pre ++ ora 子串 lse 遇到 ++i cin 字符串匹配
KMP 算法是用来处理字符串匹配问题的。也就是给你两个字符串,你需要回答:B 串是否是 A 串的子串(或 B 串在 A 串中出现的位置)。比如,字符串 A = “ i am student ”, 字符串 B = “ student ”,我们就说 B 是 A 的子串。我们称待匹配的 A 串为匹配串,用来匹配的 B 串为模式串。
如果使用普通的暴力枚举的算法,遇到个极端的例子,比如 abababababababaab 和 aab,匹配的时间复杂度会高到难以承受,为 O(nm),其中 n 为匹配串的长度,m 为模式串的长度。如果使用 KMP 算法,最坏的情况下,时间复杂度也只会是 O(n + m)。
(此处省略讲解过程,等以后再补Orz)
下面 KMP 算法的代码模板(注意,这里的 fail 数组是从 - 1 开始的)。
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1e6 + 9; 4 5 string s, t; 6 int fail[maxn]; 7 8 void get_fail(string x) { 9 int i = 0, j = -1; 10 fail[0] = -1; 11 while (x[i]) { 12 if (j == -1 || x[i] == x[j]) { 13 fail[++i] = ++j; 14 } else { 15 j = fail[j]; 16 } 17 } 18 } 19 20 int kmp(string x, string y) { 21 get_fail(y); 22 int i = 0, j = 0, res = 0; 23 int m = y.size(); 24 while (x[i]) { 25 if (x[i] == y[j]) { 26 ++i; 27 ++j; 28 if (!y[j]) { 29 ++res; 30 cout << i - m + 1 << endl; // 输出模式串在匹配串中出现的位置(从1开始计数) 31 j = fail[j]; // 匹配部分可以重叠,如果不可以重叠则直接 j = 0; 32 } 33 } else { 34 j = fail[j]; 35 if (j == -1) { 36 ++i; 37 ++j; 38 } 39 } 40 } 41 return res; // 这里返回的 res 代表模式串在匹配串中出现的次数 42 } 43 44 int main() { 45 cin >> s >> t; 46 cout << kmp(s, t) << endl; 47 return 0; 48 }
标签:pre ++ ora 子串 lse 遇到 ++i cin 字符串匹配
原文地址:https://www.cnblogs.com/CIVAN-LXYAO/p/9464127.html