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;
}
相关推荐
潇楠Web3哨兵2 小时前
桌面级Web3交易终端的底层炼狱:自研多源报价引擎、移除重型依赖、跨进程钱包桥接与强制安全拦截
算法·web3
贾斯汀玛尔斯2 小时前
每天学一个算法--回溯算法(Backtracking)
算法
cpp_25012 小时前
P2871 [USACO07DEC] Charm Bracelet S
数据结构·c++·算法·动态规划·题解·洛谷·背包dp
CoderCodingNo2 小时前
【CSP】CSP-J 2019 江西真题 | 面积 luogu-P5681 (适合GESP一级、二级考生练习)
算法
Mr_pyx2 小时前
【LeetHOT100】合并两个有序链表——Java多解法详解
算法
yu85939583 小时前
利用MATLAB进行木材图像去噪
开发语言·算法·matlab
cpp_25013 小时前
P2722 [USACO3.1] 总分 Score Inflation
数据结构·c++·算法·动态规划·题解·洛谷·背包dp
民乐团扒谱机3 小时前
【源码剖析】MATLAB混响函数底层逻辑拆解:Dattorro算法从公式到音频帧的完整推导
算法
淡海水3 小时前
【AI模型】概念-Token
人工智能·算法