KMP算法的c++实现(完整代码)

因为看了《大话数据结构》里的KMP算法的实现,里面用的是c语言的写法,因此通过学习整理思路通过C++实现

如果你看不懂为什么要这样做,建议先看看《大话数据结构》或者其他数据结构的书或资料。

首先是:get_next函数

vector<int> get_next(string b)	//用vector来保存子串b的next数组
{
	vector<int> result;		//别想着用()帮它确定大小,其实是添加元素并且默认赋值为0了,建立一个空的容器就OK了
	int i, j;
	i = 0;
	j = -1;
	result.push_back(-1);	//将容器首元素赋值,作为标识使用
	while (i < b.size() - 1)
	{
		if (j == -1 || b[i] == b[j])	//b[i]表示后缀的单个字符
										//b[j]表示前缀的单个字符
		{
			++i;
			++j;
			//这里的其实是优化重复的字符
			//可以直接用result.push_back(j);代替下面的判断语句
			if (b[i] != b[j])			
				result.push_back(j);
			else if (i == 1)
				result.push_back(j);
			else
				result.push_back(result[j]);
		}
		else
			j = result[j];		//若字符不同,前缀字符回溯
	}
	return result;
}

然后是:KMP函数

int KMP(string a, string b)
{
	vector<int> next = get_next(b);	//调用get_text函数
	int i = 0;
	int j = 0;
	//注意size函数返回的类型是string::size_type是无符号数
	//若i<主串的长度且j<子串的长度时,循环继续
	while (i < (int)a.size() && j <(int)b.size())	
	{
		if (j == -1 || a[i] == b[j])	//两字母相等则继续,相对于朴素算法增加了
		{
			++i;
			++j;
		}
		else {
			j = next[j];	//若不相等,j退回合适的位置
		}
	}
	if (j == b.size()) {
		return i - j;		//这里返回的是匹配字符开始的下标位
	}
	else {
		return -1;
	}
}

整体代码:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

vector<int> get_next(string b)	
{
	vector<int> result;
	int i, j;
	i = 0;
	j = -1;
	result.push_back(-1);	
	while (i < b.size() - 1)
	{
		if (j == -1 || b[i] == b[j])	
		{
			++i;
			++j;
			if (b[i] != b[j])
				result.push_back(j);
			else if (i == 1)
				result.push_back(j);
			else
				result.push_back(result[j]);
		}
		else
			j = result[j];
	}
	return result;
}

int KMP(string a, string b)
{
	vector<int> next = get_next(b);
	int i = 0;
	int j = 0;
	while (i < (int)a.size() && j <(int)b.size())	
	{
		if (j == -1 || a[i] == b[j])
		{
			++i;
			++j;
		}
		else {
			j = next[j];
		}
	}
	if (j == b.size()) {
		return i - j;
	}
	else {
		return -1;
	}
}

int main()
{
	string str;
	cout << "enter the string:";
	cin >> str;
	string pattern;
	cout << "enter the pattern:";
	cin >> pattern;
	int result = KMP(str, pattern);
	cout << result << endl;
}

运行结果(VS2019)
在这里插入图片描述
有很多情况还没有测试,如果有什么问题,欢迎一起探讨。

参考
https://blog.csdn.net/weixin_41106545/article/details/83573340
https://blog.csdn.net/crazy_scott/article/details/79211961?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

  • 19
    点赞
  • 103
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值