例题:pku3461(Oulipo), hdu1711(Number Sequence)
这个模板 字符串是从0开始, Next数组是从1开始。
这个模板 字符串是从0开始, Next数组是从1开始。
#include <iostream> #include <cstring> using namespace std; const int maxn = 1000005; int Next[maxn]; char s[maxn], p[maxn]; int slen, plen; void getNext() { int j, k; j = 0; k = -1; Next[0] = -1; while(j < plen) { if(k == -1 || p[j] == p[k]) { ++j; ++k; Next[j] = k; } else k = Next[k]; } } /* 返回模式串T在主串S中首次出现的位置 返回的位置是从0开始的。 */ int KMP_Index() { int i = 0, j = 0; getNext(); while(i < slen && j < plen) { if(j == -1 || s[i] == p[j]) { i++; j++; } else j = Next[j]; } if(j == plen) return i - plen; else return -1; } /* 返回模式串在主串S中出现的次数 */ int KMP_Count() { int ans = 0; int j = 0; if(slen == 1 && plen == 1) { if(s[0] == p[0]) return 1; else return 0; } getNext(); for(int i = 0; i < slen; i++) { while(j > 0 && s[i] != p[j]) { j = Next[j]; } if(s[i] == p[j]) j++; if(j == plen) { ans++; j = Next[j]; } } return ans; } int main() { int t; cin >> t; while(t--) { cin >> s >> p; slen = strlen(s); plen = strlen(p); cout << "模式串T在主串S中首次出现的位置是: " << KMP_Index() << endl; cout << "模式串T在主串S中出现的次数为: " << KMP_Count() << endl; } return 0; }