#include<iostream> #include<string> #include <math.h> #include <assert.h> #include <string.h> using namespace std; //朴素模式匹配 void Naive_String_Matcher(string T, string P) { int n = T.length(); int m = P.length(); for (int s = 0; s <= n - m; s++) { int j; for (j = 0; j < m; j++) { if (P.at(j) != T.at(j + s)) { break; } } if (j==m) { cout << "Pattern occurs at " << s << endl; } } } //Rabin_Karp 模式匹配算法 /* *T:文本串 *P:模式串 *d:进制 *q:一个素数 */ void Rabin_Karp_Matcher(string T, string P, int d, int q) { int n = T.length(); int m = P.length(); int p = 0; int t = 0; int h=1; //(d^(m-1))mod q for (int i = 0; i < m - 1; i++) { h = (h*d)%q; } for (int i = 0; i < m; i++) { p = (d*p+P[i])%q; t = (d*t + T[i]) % q; } for (int s = 0; s <= n - m; s++) { if (p == t) { int j; for (j = 0; j < m; j++) { if (P.at(j) != T.at(j+s)) break; } if (j == m) { cout << "Macther at " << s << endl; } } if (s < n - m) { t = (d*(t - T[s] * h) + T[s + m] )% q; if (t < 0) t += q; } } } //计算模式串的前缀函数 /* *比如P="abab" *t[]={0,0,1,2} *t存放的是回退的位置 */ int *Compute_Prefix_Function(string P) { int m = P.length(); int *t = new int[m]; t[0] = 0; int k = 0; for (int q = 1; q < m; q++) { while (k>0 && P[k] != P[q]) k = t[k-1]; if (P[k] == P[q]) k = k + 1; t[q] = k; } return t; } void KMP_Matcher(string T, string P) { int n = T.length(); int m = P.length(); int *t = Compute_Prefix_Function(P); for (int i = 0; i < m; i++) { cout << t[i] << endl; } int q = 0; for (int i = 0; i < n; i++) { while (q>0 && P[q] != T[i]) { q = t[q-1]; } if (P[q] == T[i]) q = q + 1; if (q == m) { cout << "Matcher at " << i - m+1 << endl; q = t[q-1]; } } delete[]t; } int main() { //string T = "acaabcaab"; //string P = "aab"; //Naive_String_Matcher(T,P); //cout << "---------------------" << endl; //Rabin_Karp_Matcher(T,P,256,127); //cout << "---------------------" << endl; string P = "abab"; string T = "ababababbc"; Compute_Prefix_Function(P); KMP_Matcher(T, P); return 0; }