#include<iostream>
#include<algorithm>
using namespace std;
void Print_LCS(int **b, string X,int m, int n);
void LCS_Length(string X, string Y)
{
int m = X.length();
int n = Y.length();
X = "0" + X;
Y = "0" + Y;
int **b = new int*[m + 1];
for (int i = 0; i < m + 1; i++)
{
b[i] = new int[n + 1];
}
int **c = new int*[m + 1];
for (int i = 0; i < m + 1;i++)
{
c[i] = new int[n + 1];
}
for (int i = 1; i < m + 1; i++)
c[i][0] = 0;
for (int j = 0; j < n + 1; j++)
c[0][j] = 0;
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= n; j++)
{
if (X.at(i) == Y.at(j))
{
c[i][j] = c[i - 1][j - 1] + 1;
b[i][j] = 1;
}
else if (c[i - 1][j]>=c[i][j - 1])
{
c[i][j] = c[i - 1][j];
b[i][j] = 0;
}
else
{
c[i][j] = c[i][j - 1];
b[i][j] = -1;
}
}
}
Print_LCS(b,X,m,n);
cout << "\n";
}
void Print_LCS(int **b, string X,int m, int n)
{
if (m == 0 || n == 0)
return;
if (b[m][n] == 1)
{
Print_LCS(b,X,m-1,n-1);
cout << X.at(m)<< " ";
}
else if (b[m][n] == 0)
{
Print_LCS(b,X, m - 1, n);
}
else
{
Print_LCS(b, X,m , n-1);
}
}
//带有备忘的LCS_LENGTH
int LoopUp_LCS(string X, string Y, int **C,int m, int n)
{
if (C[m][n] > -1)
return C[m][n];
if (m == 0 || n == 0)
C[m][n] = 0;
else
{
if (X.at(m - 1) == Y.at(n - 1))
C[m][n] = LoopUp_LCS(X,Y,C,m-1,n-1) + 1;
else
{
C[m][n] = max(LoopUp_LCS(X, Y, C, m - 1, n), LoopUp_LCS(X, Y, C, m, n-1));
}
}
return C[m][n];
}
int**Memoized_LCS_Length(string X, string Y)
{
int m = X.length();
int n = Y.length();
X = "0" + X;
Y = "0" + Y;
int **C = new int*[m + 1];
for (int i = 0; i < m + 1; i++)
{
C[i] = new int[n + 1];
}
for (int i = 0; i < m + 1; i++)
{
for (int j = 0; j < n + 1; j++)
{
C[i][j] = -1;
}
}
LoopUp_LCS(X,Y,C,m,n);
return C;
}
//KMP
int *Compute2_Prefix_Function(string P,int m)
{
int *t = new int[m + 1];
t[1] = 0;
int k = 0;
for (int q = 2; q <= m; q++)
{
while (k > 0 && P[k + 1] != P[q])
k = t[k];
if (P[k + 1] == P[q])
k = k + 1;
t[q] = k;
}
for (int i = 1; i <= m; i++)
{
cout << t[i] << " ";
}
cout << "\n";
return t;
}
void KMP2_Matcher(string T, string P)
{
int n = T.length();
int m = P.length();
T = "0" + T;
P = "0" + P;
int *t = Compute2_Prefix_Function(P, m);
int q = 0;
for (int i = 1; i <= n; i++)
{
while (q > 0 && P[q + 1] != T[i])
q = t[q];
if (P[q + 1] == T[i])
q = q + 1;
if (q == m)
{
cout << "macther at " << i - m;
q = t[q];
}
}
cout << "\n";
}
int main()
{
string X = "ABCBDAB";
string Y = "BDCABA";
LCS_Length(X,Y);
int **C = Memoized_LCS_Length(X, Y);
for (unsigned i = 0; i < X.length() + 1; i++)
{
for (unsigned j = 0; j < Y.length(); j++)
{
cout << C[i][j] << "\t";
}
cout << "\n";
}
cout << "\n";
X = "ababababbc";
Y = "ababbc";
KMP2_Matcher(X,Y);
return 0;
}