KMP算法(C++实现)

KMP算法学了半天,自己也敲了半天,终于搞懂了一些,在此做下总结,方便日后复习,也可供读者参考。

求next数组

vector<int>nex;//nex数组即next数组,因为c++存在同名情况,所以用nex表示 
void get_next(string ss)//获取next数组的函数 
{
	/*i指向已匹配字符串的下一个位置
	j指向最长公共前后缀的下一个位置 */ 
	int i,j;
	nex.resize(ss.length());//数组设置为字符串ss的大小 
	nex[0]=-1;//子串第一个位置前不存在已匹配的前后缀,所以置为-1 
	nex[1]=0;//子串第二个位置前也不存在公共前后缀,但是置为0,方便后续操作 
	i=2;
	j=0;
	while(i<ss.length())
	{
		if(ss[i-1]==ss[j])//相等则加1 
		{
			nex[i]=nex[i-1]+1;
			j++;
		}
		else
		{
			while(ss[i-1]!=ss[j]&&j>0)//不相等则回溯 
				j=nex[j]; 
			nex[i]=j;
		}
		i++;
	}
}

 匹配操作主函数

int main()
{
	string s,ss;
	int i,j,len_s,len_ss;
	cin>>s>>ss;
	get_next(ss);
	i=j=0;
	len_s=s.length();
	len_ss=ss.length();
    while(i<len_s&&j<len_ss)
	{
		if(s[i]==ss[j]||j==-1)//j为-1时或字符匹配时的情况 
		{
			i++;
			j++;
		}
		else
			j=nex[j];//不匹配时则查询next数组 
	} 
	if(j==ss.length())//此情况则说明匹配成功 
		cout<<i-len_ss+1;//输出子串在主串中的位置 
	else
		cout<<"Not found";//匹配失败,找不到 
	return 0;
}

 汇总代码

#include <iostream>
#include <string> 
#include <vector>
using namespace std;
vector<int>nex;//nex数组即next数组,因为c++存在同名情况,所以用nex表示 
void get_next(string ss)//获取next数组的函数 
{
	/*i指向已匹配字符串的下一个位置
	j指向最长公共前后缀的下一个位置 */ 
	int i,j;
	nex.resize(ss.length());//数组设置为字符串ss的大小 
	nex[0]=-1;//子串第一个位置前不存在已匹配的前后缀,所以置为-1 
	nex[1]=0;//子串第二个位置前也不存在公共前后缀,但是置为0,方便后续操作 
	i=2;
	j=0;
	while(i<ss.length())
	{
		if(ss[i-1]==ss[j])//相等则加1 
		{
			nex[i]=nex[i-1]+1;
			j++;
		}
		else
		{
			while(ss[i-1]!=ss[j]&&j>0)//不相等则回溯 
				j=nex[j]; 
			nex[i]=j;
		}
		i++;
	}
}
int main()
{
	string s,ss;
	int i,j,len_s,len_ss;
	cin>>s>>ss;
	get_next(ss);
	i=j=0;
	len_s=s.length();
	len_ss=ss.length();
    while(i<len_s&&j<len_ss)
	{
		if(s[i]==ss[j]||j==-1)//j为-1时或字符匹配时的情况 
		{
			i++;
			j++;
		}
		else
			j=nex[j];//不匹配时则查询next数组 
	} 
	if(j==ss.length())//此情况则说明匹配成功 
		cout<<i-len_ss+1;//输出子串在主串中的位置 
	else
		cout<<"Not found";//匹配失败,找不到 
	return 0;
}

 接着来说说自己遇到的坑:1.while(i<len_s&&j<len_ss)和while(i<s.length()&&j<ss.length()),后者会出错,原因是length()函数返回时的类型转换有蹊跷

感谢这篇博文:while与string::length()使用的错误

2.c++中使用next命名的数组会报错,原因竟然是包含的头文件中有同名函数

感谢这篇博文:c++的next

最后:在学习KMP过程中,感谢以下博文,是它们给了我思路,教会了我KMP算法

ACM选手带你玩转KMP算法

漫画:什么是KMP算法?

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值