朴素的模式匹配算法:
#include<iostream>
#include<string>
using namespace std;
#pragma warning(disable : 4996)
int stringMathching(string S, string P);
int main() {
string S = "abcfsxyzabh";
string P = "xyz";
int result = stringMathching(S, P);
cout << "result:" << result << endl;
return 0;
}
int stringMathching(string S, string P) {
int result = -1;
//将两个字符串转化为字符数组
char * s = new char[S.length()];
strcpy(s, S.c_str());
char * p = new char[P.length()];
strcpy(p, P.c_str());
for (int i = 0; i <= S.length()-P.length(); i++) {
int j = 0;
int temp_i = i;
while (s[temp_i] == p[j]&&j<P.length()) {
j++;
temp_i++;
}
if (j == P.length()) {
result = i+1;
break;
}
}
return result;
}
KMP算法:当米一次匹配过程中出现不匹配字符时,不需要回退指针,而是利用已经得到的“部分匹配”结果将模式向右滑动尽可能元的距离后,继续匹配过程。
该算法的关键是计算f(j),即在p0p1p2…pj中找到最大的前后相等的子串,使得:
p0p1…pk=pj-k pj-k+1 …pk
f(j)=k
如果没有这样的子串,则f(j)=-1.
代码:
#include<iostream>
#include<string>
using namespace std;
#pragma warning(disable : 4996)
int stringMathching(string S, string P);
int * fail(string P);
int main() {
string S = "abcfsxyzabh";
string P = "xyz";
int result = stringMathching(S, P);
cout << "result:" << result << endl;
system("pause");
return 0;
}
int stringMathching(string S, string P) {
int result = -1;
//将两个字符串转化为字符数组
char * s = new char[S.length()];
strcpy(s, S.c_str());
char * p = new char[P.length()];
strcpy(p, P.c_str());
int * f = fail(P);
int i = 0;
int j = 0;
while (i <= S.length() - P.length()&&j<P.length()) {
if (s[i] == p[j]) {
i++;
j++;
}
else if (j == 0) {
i++;
}
else {
j = f[j - 1] + 1;
}
}
if (j == P.length())
result = i - P.length();
return result;
}
int * fail(string P) {
int m = P.length();
char * p = new char[m];
strcpy(p,P.c_str());
int * f = new int[m];
f[0] = -1;
int i;
for (int j = 1; j < m; j++) {
i = f[j - 1];
while (p[j] != p[i + 1] && i > 0)
i = f[i];
if (p[j] == p[i + 1])
f[j] = i + 1;
else
f[j] = -1;
}
return f;
}