kmp算法

57 篇文章 0 订阅

匹配的过程是这样的

 

已知空格与D不匹配时,前面六个字符"ABCDAB"是匹配的。查表可知,最后一个匹配字符B对应的"部分匹配值"为2,因此按照下面的公式算出向后移动的位数:

  移动位数 = 已匹配的字符数 - 对应的部分匹配值

因为 6 - 2 等于4,所以将搜索词向后移动4位。

10.

因为空格与C不匹配,搜索词还要继续往后移。这时,已匹配的字符数为2("AB"),对应的"部分匹配值"为0。所以,移动位数 = 2 - 0,结果为 2,于是将搜索词向后移2位。

11.

因为空格与A不匹配,继续后移一位。

12.

逐位比较,直到发现C与D不匹配。于是,移动位数 = 6 - 2,继续将搜索词向后移动4位。

13.

逐位比较,直到搜索词的最后一位,发现完全匹配,于是搜索完成。如果还要继续搜索(即找出全部匹配),移动位数 = 7 - 0,再将搜索词向后移动7位,这里就不再重复了。

 

代码,这里面最主要的是next数组的求法,其中最重要的是又是当求next中两个点数据不一样的时候,该如何计算。

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;

void Next(string s, vector<int> &next)
{
	int p, k;
	next[0] = 0;
	for (int p = 1, k = 0; p < s.size(); p++)
	{
		while (k>0&&s[p] != s[k])//相当于求k+1个和第p个是否匹配,这个匹配就是最大的匹配串了
		{
			k = next[k - 1];//因为是从0开始索引的,所以s[k]相当于第k+1个
		}
		if (s[p] == s[k])
		{
			k++;
		}
		next[p] = k;
	}
}
void kmp(string s1, string s2, vector<int> &next)//s2长串,s1短串
{
	int len1 = s1.size();
	int len2 = s2.size();
	Next(s2,next);
	int p1 = 0;
	int p2 = 0;
	for (; p1 < len1;p1++)//长串搜索结束为止
	{
		while (p2 > 0 && s2[p2] != s1[p1])//相当于求s2的第p2个和s1的第p1个是否匹配
		{
			p2 = next[p2 - 1];//前面的next[p2-1]肯定是匹配的
		}
		if (s2[p2] == s1[p1])
			p2++;
		if (p2 == len2)
		{
			cout << "匹配成功" << p1 << endl;
			break;
		}
	}
}
int main()
{
	vector<int> next(100, 0);
	string s1, s2;
	cin >> s1 >> s2;
	kmp(s1, s2, next);
	system("pause");
	return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值