KMP算法

kmp算法是对字符串暴力匹配算法的优化,主要通过next数组记录最大的相等的前缀和后缀长度进行优化。

KMP原理

理解kmp算法首先要知道前缀和后缀两个概念,前缀 是除了最后一个字符外字符串所有的头部子串,后缀 是除了第一个字符外字符串所有的尾部子串,例如"ababa"的前缀就是{a,ab,aba,abab}后缀就是{a,ba,aba,baba}。在字符串匹配过程的中,如果模式串的前j个字符与主串的a~a+j字符匹配,第j+1个字符与a+j+1不同,而且模式串前j个字符的最大相同前后缀长度是x即模式串的0~x-1与j-x+1~j相同那么第j+1个字符与a+j+1不同时就不需要从模式串的第0个字符开始匹配而是从第x个字符匹配,从而减少了匹配时间,这就是kmp算法通过记录模式串最大相同前缀后缀长度减少匹配时间的方式。

next数组

从kmp算法的原理中不难看出最重要的部分就是求最大相同前后缀长度也就是next数组,我个人理解的next数组是求模式串前j字符最大前后缀长度,那么在字符串匹配的过程中第j+1个字符不匹配,模式串就只需要从第next[j]个字符开始重新匹配j+1=next[j](坐标从0开始长度是next[j]),也有的是next数组是next[j]表示前j-1个字符的最大前后缀长度,那么i=next[j]。前n-1个字符的最大相同前后缀和是j-1,如果j==i则next[i]=j,如果不同则比较next[j-1],因为next[j-1]=x可以保证 【0,x-1】=【i-x+1,i】而且若next[i]=a,则【0,a-1】=【i-a+1,i】,【0,a-2】=【i-a+1,i-1】又因为next[i-1]=b=j-1,则【i-a+1,i-1】=【b-a+2,b】=【0,a-2】则next[b]>=a-1,即next[i]一定在next[j-1]中,所以用next[j-1]可以确定是i的最大相同前后缀长度求next数组的时候就是在用kmp,把 【0,j】 的前缀看成是模式串,把 【1,i】 的后缀看成是文本串,①文本串一直是每次循环+1,不会回退 ②模式串有时候可以通过next数组跳过前面几个字符直接比较。

代码实现

cpp 复制代码
#include<string>
#include<vector>
#include<iostream>
using namespace std;
void GetNext(string& s,vector<int>& next)
{
	int i = 1;
	int j = 0;
	next[0] = 0;
	for (; i < next.size(); i++)
	{
		if (s[i] == s[j])
		{
			next[i] = ++j;
			continue;
		}
		while (s[i] != s[j]&&j>0)
		{
			j = next[j - 1];
		}
		if (s[j] != s[i]) next[i] = 0;
		else next[i] = ++j;
	}
}
int Index(string& s, string& t)
{
	vector<int> next(t.size(), 0);
	GetNext(t, next);
	int i = 0;
	int j = 0;
	while(i<s.size()&&j<t.size())
	{
		if (s[i] == t[j])
		{
				i++;
				j++;
		}
		else if (j == 0)
		{
			i++;
		}
		else 
			j = next[j - 1];
	}
	if (j == t.size())
		return i - t.size();
	else
		return -1;
}
int main()
{
	string s = "anssna";
	string t = "sna";
	cout << Index(s, t);
	return 0;
}
相关推荐
YL200404265 小时前
048路径总和III
数据结构·dfs
z200509306 小时前
每日简单算法题——————跟着卡尔
算法
️是787 小时前
信息奥赛一本通—编程启蒙(3395:练68.3 车牌问题)
数据结构·c++·算法
Liangwei Lin7 小时前
LeetCode 118. 杨辉三角
算法·leetcode·职场和发展
计算机安禾7 小时前
【c++面向对象编程】第24篇:类型转换运算符:自定义隐式转换与explicit
java·c++·算法
鼠鼠我(‘-ωก̀ )好困7 小时前
leetGPU
算法
我星期八休息7 小时前
Linux系统编程—基础IO
linux·运维·服务器·c语言·c++·人工智能·算法
池塘的蜗牛7 小时前
A Low-Complexity Method for FFT-based OFDM Sensing
算法
故事和你918 小时前
洛谷-【图论2-1】树5
开发语言·数据结构·c++·算法·动态规划·图论
咖啡里的茶i8 小时前
视觉显著目标的自适应分割与动态网格生成算法研究
人工智能·算法·目标跟踪