首页 > 其他分享 >kmp + exkmp

kmp + exkmp

时间:2023-04-20 19:56:37浏览次数:40  
标签:exkmp nxt 匹配 int kmp 区间

kmp :主要就是用于暴力回退的优化 一般的暴力回退总是回退到前一个 ,要枚举很多次 如果找到规律那么就会发现可以找到上一次最大匹配的位置然后将继续匹配知道匹配不下去然后去更新
代码
kmp是前缀 到某一个为停止

#include <bits/stdc++.h>
using namespace std;
int n,m;
int nxt[M+1],f[N+1];
char s[N+2],p[M+2];     //p数组是去配对的数组  s是被配对的!
void kmp()
{
	n=strlen(s+1);
	m=strlen(p+1);
	int j=0;
	nxt[1]=0;
	for(int i=2;i<=m;i++)//直接去拿目标数组去弄是一样的!!本质上找的就是一个前缀等于后缀
		//那么就是一样的呢1
	{
		while(j>0&&p[j+1]!=p[i])   
		j=nxt[j];
		if(p[j+1]==p[i])
		j++;//找到一样的在当前的位置++就是到了下一个
		//如ababac
		//ababac   //第一个本身就是0退无可退 那么第二个又不相等
		//001230  c这里:目前是j是3但是4所代表的不和c一样故3=nxt[3]=1 退到一去 
		nxt[i]=j;//否则就是0
	}
	j=0;
	for(int i=1;i<=n;i++)
	{
		while((j==m)||(j>0&&p[j+1]!=s[i]))//当前已经匹配到最后了
			j=nxt[j];//那么说明不能再往后匹配了
		if(p[j+1]==s[i])
			j++;
		f[i]=j;//能	匹配到第几个!!
	}
}
int main(){}

关键就在于nxt数组的理解:本质上就是p,对p求nxt,跟你被匹配的数组无关 主要就是看如果下一位配不上了我能跳到哪一位知道下一位可以匹配得上 如果实在匹配不上那么就从0开始!!
最长公共前后缀本质就是一个nxt数组,只要明白nxt究竟是个啥就可以啦!!就是由nxt去匹配
p和p+1 去匹配得到的nxt。

接下来就是exkmp
exkmp是从某个位置开始的匹配 ,本质就是维护了一个区间在这个区间的东西和前面的完全相同
而前面的情况之前已经在最开始的

void exkmp()  //最长公共   以第i位开始向后匹配(匹配是从开头开始!
{
	int l=1,r=0;
	z[1]=0; //定义的 从2到n枚举!!   
	//分为多种情况  L记录的最大长度时的i值(若此时的从新的i开始的区间更大 才会被更新 因为记录区间开头这并不重要主要就是区间的结尾!!
	// R 当匹配的区间右端点大于R时才会被更新否则不会被更新! 
	for(int i=2;i<=n;i++)
	{
		if(i>r)//目前的数不在区间内
		{
			z[i]=0;
		}else {
			int k=i-l+1;  //对应  1  -- r-l+1 区间内的数
			z[i]=min(z[k],r-i+1);// 左边是在1 -  r-l+1区间中i对应的位置的z[k]的值若z[k]的值比这个区间的长度都大那么就
			//从第i个位置开始和前面的相等那么就像映射只能保证到r这个位置是一样的超过这个大小就不能保证d
			//故取最小值
			//因为只保证了 从k开始后和i开始后是一样的 那么超过 r-i+1后就不能再保证了
		}
	while(i+z[i]<=n&&s[z[i]+1]==s[z[i]+i])  //之后向后面暴力去找!     z[i]是长度 第一个就枚举第一个位置和当前i的位置是否相等
		++z[i];
	if(i+z[i]-1>r)//只要i>r时有一个配对上会更新!!
		l=i,r=i+z[i]-1;
	}
}


https://www.luogu.com.cn/problem/P4391
这一题是kmp的典型题目

标签:exkmp,nxt,匹配,int,kmp,区间
From: https://www.cnblogs.com/--Lance/p/17338113.html

相关文章

  • 26、字符串匹配 KMP 算法
    1、KMP算法的基本原理2、KMP算法的正确性证明3、什么是LPS数组4、LSP数组的计算5、实现LPS数组6、KMP算法的实现7、复杂度分析......
  • KMP算法
    KMP算法要解决的问题就是在字符串(也叫主串)中的模式(pattern)定位问题。说简单点就是我们平时常说的关键字搜索。模式串就是关键字(接下来称它为P),如果它在一个主串(接下来称为T)中出现,就返回它的具体位置,否则返回-1(常用手段)。这里面的前缀集表示除去最后一个字符后的前面的所有子串集合,同......
  • 字符串匹配算法KMP
    KMP算法是字符串的匹配算法,比如我给一个名为《文本》的字符串,和一个名为《样板》的字符串,询问《样板》在《文本》中出现过的次数,这就需要字符串匹配算法。对于匹配,形象一点可以看例子:《文本1》="abcdefghigklmn"《样板1》="abc"=============================《文本2》="abcde......
  • (KMP 1.1)hdu 1711 Number Sequence(KMP的简单应用——求pattern在text中第一次出现的
    题目:NumberSequenceTimeLimit:10000/5000MS(Java/Others)    MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):12902    AcceptedSubmission(s):5845ProblemDescriptionGiventwosequencesofnumbers:a[1],a[2],......,a[N],andb[1......
  • KMP算法(串的模式匹配算法)(未完待续......)
    KMP算法的实现1.基本原理  在暴力破解算法(BF算法)中,模式串需要一个一个来跟主串进行对比,若有一个不相同,则主串前进一位,继续从头开始进行比较,这样比较的最坏时间复杂度为O(mn),例:‘aaaaaaaaab’和‘aaab’,需要比较到最后一个才能成功,效率太过低下。  KMP算法的原理是,找到模式串......
  • KMP 字符串
    KMP题目描述给定一个字符串\(S\),以及一个模式串\(P\),所有字符串中只包含大小写英文字母以及阿拉伯数字。模式串\(P\)在字符串\(S\)中多次作为子串出现。求出模式串\(P\)在字符串\(S\)中所有出现的位置的起始下标。输入第一行输入整数\(N\),表示字符串\(P\)的长度......
  • KMP
    2021年就学了KMP,2023写一篇详细点的总结。首先我们需要理解朴素做法。枚举开始匹配的位置\(i\),和匹配串中的每个位置逐一匹配,失败就停止移动继续匹配,最坏情况复杂度高达\(O(mn)\)上述做法的缺陷就在于没有充分利用信息,比如匹配失败时就从头开始。我们考虑一次匹配中,如果失......
  • KMP算法
    一、问题引入BF算法的平均时间复杂度过高,提出了一种新的匹配算法KMP算法。主串S的位置i一直往下移动,不再回溯。但字串T的位置j需要根据算法确定下来。二、解决过程函数:get_next()voidget_next(constchar*T,int**next){ inti=0,j=-1; intT_len=strlen(T......
  • KMP算法--模板
    生成Pattern的字符串的next数组,长度为m+1点击查看代码voidgetNext(vector<int>&next,string&pattern){intn=pattern.size();for(intj=0,k=-1;j<n;){if(k==-1||pattern[j]==pattern[k])next[++j]=++k;......
  • KMP字符串匹配算法
     KMP算法的要点是避免回溯和Next[]数组,其中,Next[]数组中存的是最长公共前后缀的长度. 1.KMP模板例题:HDU2087剪花布条 intNext[N],cnt;//构建Next[]数组voidg......