KMP

KMP算法

模式串p:就是需要寻找的那个串
文本串t:就是一个待与模式串p匹配的字符串
作用:
1.求出模式串p在文本串中出现的位置
2.求出模式串长度为i的前缀的最长的border(就是nxt[]数组,获取失配指针的数组)

算法思想:
充分利用模式串p,使得之前被匹配过的地方不再多匹配
观察一下模式串,你会发现在匹配的部分里,存在相同前后缀的部分( KMP 算法的核心)
与文本串匹配时,失配之后,利用某一部分前缀快速移动到对应在匹配的串中的后缀位置
去掉了很多无意义的匹配和回溯,大大提高了效率
现在的问题成了每次不匹配的时候,找之前已匹配部分中,模式串的前后缀,而且还是最长公共前后缀
nxt[i]数组记录匹配到模式串的第i位之后失配,该跳转到模式串的哪个位置(对应后缀),
那么对于模式串的第一位和第二位而言,只能回跳到1
写得极好的图解 https://zhuanlan.zhihu.com/p/469773163

//luoguP3375 KMP字符串匹配
#include <bits/stdc++.h>
using namespace std;

const int N=1e6+10;

int nxt[N];
void getfail(char *p) {
	
	int m=strlen(p+1),j=0;
	nxt[0]=0;
	nxt[1]=0;
	for(int i=2;i<=m;i++) {
		
		while(j&&p[i]!=p[j+1]) j=nxt[j];
		if(p[i]==p[j+1]) j++;
		nxt[i]=j;
		
	}
	
}

void kmp(char *t,char *p) {
	
	int n=strlen(t+1);
	int m=strlen(p+1);
	getfail(p);
	int j=0;
	for(int i=1;i<=n;i++) {
		
		while(j&&t[i]!=p[j+1]) j=nxt[j];
		if(t[i]==p[j+1]) j++;
		if(j==m) {
			
			printf("%d\n",i+1-m);
			j=nxt[j];
			
		}
		
	}
	
}

char p[N],t[N];

int main() {
	
	cin>>(t+1)>>(p+1);
	kmp(t,p);
	int m=strlen(p+1);
	for(int i=1;i<=m;i++) {
		
		printf("%d ",nxt[i]);
		
	}
	
	return 0;
}

posted @   Diamondan  阅读(15)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示