KMP
1 const int maxn = 1e5 + 5; 2 int n, m; // n 主串长度, m模式串长度 3 string a, b; // a 主串, b 模式串, 下标从零开始 4 int _next[maxn], nextval[maxn]; 5 void get_next() { 6 int i = 0, j; 7 j = _next[0] = -1; 8 while (i < m) 9 { 10 if (-1 == j || b[i] == b[j]) 11 _next[++i] = ++j; 12 else 13 j = _next[j]; 14 } 15 } 16 17 void get_nextval() { 18 int i = 0, j; 19 j = nextval[0] = -1; 20 while (i < m) { 21 if (-1 == j || b[i] == b[j]) { 22 ++i, ++j; 23 nextval[i] = (b[i] != b[j]) ? j : nextval[j]; 24 } 25 else { 26 j = nextval[j]; 27 } 28 } 29 } 30 31 int kmp_index(int pos) { 32 // 求模式串在主串 pos位置 字符之后的位置 33 int i = pos, j = 0; 34 while (i < n && j < m) { 35 if (-1 == j || a[i] == b[j]) { 36 ++i, ++j; 37 } 38 else { 39 j = nextval[j]; 40 } 41 } 42 if (j >= m) return i - m; 43 else return -1; 44 } 45 46 int kmp_count(int pos) { 47 // 求模式串在主串中出现了几次 48 int i = pos, j = 0; 49 int ans = 0; 50 while (i < n) { 51 if (-1 == j || a[i] == b[j]) { 52 ++i, ++j; 53 if (j >= m) { 54 ++ans; 55 //q.push(i); 56 j = nextval[j]; 57 } 58 } 59 else 60 j = nextval[j]; 61 } 62 return ans; 63 } 64 65 int main() 66 { 67 cin >> a >> b; 68 n = a.size(); m = b.size(); 69 get_next(); 70 get_nextval(); 71 int Index = kmp_index(0); 72 int Count = kmp_count(0); 73 cout << Index << ' ' << Count << endl; 74 return 0; 75 }