模式匹配

朴素的模式匹配算法:

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值