首页 > 其他分享 >KMP

KMP

时间:2024-10-18 19:33:16浏览次数:1  
标签:nxt 前缀 int 串为 KMP pi size

一个 kmp 学了 \(n\) 遍终于学懂的屑菜 bot。

下文默认文本串为 \(s\),模式串为 \(t\)。

前缀函数

定义

\(\pi_i\) 表示前缀为 \(i\) 的子串中的最长公共前后缀(border)长度。

不难发现,将文本串接在模式串后,中间隔一个特殊字符,若出现 \(\pi_i = |t|\) 的情况则说明匹配成功了。

求取

暴力

\(O(n ^ 3)\) 去暴力枚举。

高效算法

第一个重要的观察是相邻的前缀函数值至多增加 \(1\)

那么我们就是要往前查找一个尽可能大的 \(\pi\) 满足其往后一位仍然能匹配,或直到 border 长度为 \(0\)。

具体地可以依照这个视频来看,讲得非常详细。

模板

不难发现实现起来非常之短。

n = s.size(), m = t.size();
	
	s = t + '?' + s;
	
	for(int i = 1, j = nxt[i - 1] ; i < (int)s.size() ; ++ i) {
		while(j && s[i] != s[j]) j = nxt[j - 1];
		
		if(s[i] == s[j]) {
			nxt[i] = ++ j;
			
			if(nxt[i] == m) cout << i - m * 2 + 1 << '\n', j = nxt[j - 1];
		} 
	}

标签:nxt,前缀,int,串为,KMP,pi,size
From: https://www.cnblogs.com/endswitch/p/18474586

相关文章

  • Z函数(扩展KMP)
    扩展KMP(Z函数)Z数组简单理解\(Z[i]\)表示字符串从i出发,与整体相比有多长的公共前缀aaabaac7210210可以先理解马拉车再来看首先,设置两个类似的东西,关键点\(c\)和最右边界\(r\),表示\(Z[c]\)是目前所有\(Z\)中,\(i+Z[i]\)最右边的那个对于: r01......
  • 对KMP算法的疑问与理解
    对KMP算法的疑问与理解核心:在逐字符遍历主串与模式串的过程中,发生失配时,不回溯主串的i字符指针,而是通过确定已经匹配过的模式串的子串的前缀集合与后缀集合的交集中最长元素的长度,来移动模式串的j字符指针,实现模式串的整体向右滑动,跳过绝不可能发生的字符串匹配,以此实现......
  • [NOI2014] 动物园——KMP 倍增
    [NOI2014]动物园题目描述近日,园长发现动物园中好吃懒做的动物越来越多了。例如企鹅,只会卖萌向游客要吃的。为了整治动物园的不良风气,让动物们凭自己的真才实学向游客要吃的,园长决定开设算法班,让动物们学习算法。某天,园长给动物们讲解KMP算法。园长:“对于一个字符串\(S\),它......
  • kmp算法模板
    voidkmp(){n=strlen(s+1);//s是目标串m=strlen(p+1);//p是模板串//nxt预处理开始intj=0;nxt[1]=0;for(inti=2;i<=m;i++){while(j>0&&p[j+1]!=p[i])/*判断当前子串的前后缀相等的长度是否能增......
  • KMP循环节
    KMP循环节在icpc2019ChinaCollegiateProgrammingContestQinhuangdaoOnsiteJ.MUVLUVEXTRA由题易得,要求这个数的小数部分的\(S=a×循环长度−b×循环节的长度\),让这个S尽可能的大。又因为对于循环长度我们可以用kmp算法来求出最小循环节,所以我们可以枚举循环长度......
  • 洛谷题单指南-字符串-P3375 【模板】KMP
    原题链接:https://www.luogu.com.cn/problem/P3375题意解读:给定两个字符串:原串s,模式串p,求p在s中出现的所有位置,并输出p的长度为1~p.size()的子串的最长相同真前、后缀的长度。解题思路:KMP模版题,分两问,第一问通过KMP核心算法实现,第二问输出模式串的Next数组内容,接下来一一解读。......
  • KMP算法
    引言之前在打ACM竞赛时就学过一些字符串相关的算法,其中就包括KMP。但是面向竞赛的KMP算法和面向408的KMP算法在一些概念和实现细节上有细微差异,所以特意写了这篇文章对408中的KMP算法做出总结字符串的前缀、后缀和部分匹配指前缀指除了最后一个字符以外,字符串的所有头部子串;后......
  • 8592 KMP算法
    首先,我们需要理解KMP算法的基本思想。KMP算法是一种改进的字符串匹配算法,它的主要思想是利用已经部分匹配的这个有效信息,使得后续的匹配中,尽量减少字符串的回溯,提高匹配效率。KMP算法的关键在于通过一个next数组,保存模式串中前后缀的最长的共有元素的长度。当模式串中的字符......
  • 字符串从入门到退竞(2)——KMP 算法
    约定在文字描述中字符串下标从\(1\)开始,代码中从\(0\)开始。前缀函数对于长\(n\)的字符串\(S\),其前缀函数是一个长\(n\)的数组(数列)\(\pi\),定义如下:若\(S[1..i]\)有相等的真前缀和真后缀(称之为border),\(\pi[i]\)为其长度的最大值;若不存在,\(\pi[i]=0\)。字符串的......
  • 【算法】C++KMP算法的简洁实现
    目录简介next数组匹配完整代码简介对于朴素的字符串匹配算法,如果想在主串中寻找到第一次出现子串的位置,需要依次枚举主串中的每一个位置作为起始位置进行匹配尝试,如果主串中存在许多与子串相似结构的部分,那么朴素算法会进行大量的无用枚举,时间复杂度非常之高。KMP算法......