字符串匹配KMP
KMP
返回s串中匹配p串成功后第一个字符的下标,若要返回位置,则+1
#include<iostream> #include<string> using namespace std; int _next[1000010]; string s, p; void getnext(string p){ _next[0] = -1; int j = -1, i = 0; while (i<p.length() - 1){ //p[j]表示前缀,p[i]表示后缀 if (j == -1 || p[i] == p[j]){ i++; j++; _next[i] = j; } else j = _next[j]; } } int kmp(string s, string p){ getnext(p); int i = 0, j = 0; while (i<s.length()){ if (j == -1 || s[i] == p[j]){ i++; j++; } else j = _next[j]; if (j == p.length()){ return i - j; } //返回s串中出现得到第一个字符的下标,若是位置,则+1 } return -1; //没有匹配成功 } int main(){ ios::sync_with_stdio(false); cin >> s >> p; cout << kmp(s, p) << endl; return 0; }
返回s串中一共出现过几次p串(分为可重叠和不可重叠,在代码中有体现)
#include<iostream> #include<string> using namespace std; int _next[1000010]; string s, p; void getnext(string p){ _next[0] = -1; int j = -1, i = 0; while (i<p.length() - 1){ //p[j]表示前缀,p[i]表示后缀 if (j == -1 || p[i] == p[j]){ i++; j++; _next[i] = j; } else j = _next[j]; } } int kmp(string s, string p){ getnext(p); int i = 0, j = 0; int res = 0; //记录次数 while (i<s.length()){ if (j == -1 || s[i] == p[j]){ i++; j++; } else j = _next[j]; if (j == p.length()){ res++; i--; j--; j = _next[j]; } //若不能重叠,则去掉这里的i--;j--; } return res; } int main(){ ios::sync_with_stdio(false); cin >> s >> p; cout << kmp(s, p) << endl; return 0; }

浙公网安备 33010602011771号