#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;
}