首页 > 编程语言 >KMP字符串匹配算法

KMP字符串匹配算法

时间:2023-03-25 21:36:00浏览次数:54  
标签:int void Next char 算法 KMP 字符串 plen

  KMP算法的要点是避免回溯和Next[]数组,其中,Next[]数组中存的是最长公共前后缀的长度.   1.KMP模板

例题:HDU2087剪花布条

 

int Next[N],cnt;
//构建Next[]数组 void getNext(char *p,int plen){ Next[1]=Next[0]=0; for(int i=1;i<plen;i++){ int j=Next[i]; while(j&p[i]!=p[j])j=Next[i]; if(p[i]==p[j])Next[i+1]=j+1; else Next[i+1]=0; } }
//KMP算法 void kmp(char *s,char *p){ int last=-1,slen=strlen(s),plen=strlen(p); getNext(p,plen); int j=0; for(int i=0;i<slen;i++){ while(j&&s[i]!=p[j])j=Next[j]; if(s[i]==p[j])j++; if(j==plen){ if(i-last>=plen){ cnt++; last=i; } } } }

  

2.DP+KMP

例题:HDU3336

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+9,MOD = 1e4+7;
int dp[N],nex[N];
char s[N];
int len1,len2;
void getnext(){
    int i=0,j=-1;
    nex[i]=j;
    while(i<len1){
        if(j==-1||s[i]==s[j])nex[++i]=++j;
        else j=nex[j];
    }
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int sum=0;
        scanf("%d",&len1);
        scanf("%s",&s);
        memset(dp,0,sizeof(dp));
        getnext(); 
        for(int i=1;i<=len1;i++){
            dp[i]=dp[nex[i]]+1;
            sum=(sum+dp[i])%MOD;
        }
        printf("%d\n",sum);
    }
    return 0;
}

  

3.矩阵快速幂+KMP

例题:洛谷P3193

#include<bits/stdc++.h>
#include<ext/rope>
using namespace std;
using namespace __gnu_cxx;
const int N = 5e3+255;
int f[N][30],n,m,k,nxt[N],match[N][50];
char md[N];
void kmp(){
	nxt[0]=-1;
	for(int i=1;i<=m;i++){
		int j=nxt[i-1];
		while(j!=-1&&md[j+1]!=md[i])j=nxt[j];
		nxt[i]=++j;
	}
	nxt[0]=0;
	for(int i=0;i<m;i++){
		for(int j='0';j<='9';j++){
			int t=i;
			while(md[t+1]!=j&&t>0)t=nxt[t];
			if(md[t+1]==j)t++;
			if(t<m)match[i][t]++;
		}
	}
}
class matrix{
	public:
		int mr[25][25];
		matrix(){
			memset(mr,0,sizeof(mr));
		}
		matrix operator *(matrix b){
			matrix ans;
			memset(ans.mr,0,sizeof(ans.mr));
			for(int i=0;i<m;i++){
				for(int j=0;j<m;j++){
					for(int p=0;p<m;p++){
						ans.mr[i][j]+=mr[i][p]*b.mr[p][j];
						ans.mr[i][j]%=k;
					}
				}
			}
			return ans;
		}
}F,G;
matrix quickPow(matrix A,int pows){
	matrix ans;
	for(int i=0;i<=m;i++)ans.mr[i][i]=1;
	while(pows){
		if(pows&1)ans=ans*A;
		pows>>=1;
		A=A*A;
	}
	return ans;
}
int main(){
	cin>>n>>m>>k;
	scanf("%s",md+1);
	kmp();
	F.mr[0][0]=1;
	for(int i=0;i<=m;i++){
		for(int j=0;j<=m;j++){
			G.mr[i][j]=match[i][j];
		}
	}
	G=quickPow(G,n);
	F=F*G;
	long long ans=0;
	for(int i=0;i<m;i++){
		ans+=F.mr[0][i];
		ans%=k;
	}
	cout<<ans;
	return 0;
}

  

 

标签:int,void,Next,char,算法,KMP,字符串,plen
From: https://www.cnblogs.com/zhanghx-blogs/p/17255646.html

相关文章

  • 实验2 字符串和列表
    实验任务1源代码1x='nbaFIFA'2print(x.upper())3print(x.lower())4print(x.swapcase())5print()67x='abc'8print(x.center(10,'*'))9print(......
  • 用C语言实现ElGamal算法
    缘起是我侄子问的题目,参考了书籍、博客,花了一些时间完成的,丢掉可惜了,记录下来吧。这个程序还有些缺陷,数值太大时计算结果会溢出代码#include<stdio.h>#include<time.h>......
  • 由“交卷”功能引发的思考——对比两个字符串数组的差异
    最近在做一个答题系统,在交卷的时候需要判断客观题的答题情况客观题的题型有单选题、多选题、判断题其中判断题可以当做单选题处理,而单选题也可以当做标准答案长度为一的......
  • 算法总结--ST表
    声明(叠甲):鄙人水平有限,本文为作者的学习总结,仅供参考。1.RMQ介绍在开始介绍ST表前,我们先了解以下它以用的场景RMQ问题。RMQ(RangeMinimum/MaximumQuery)问......
  • m基于分段蚁群算法优化SVM的数据预测matlab仿真
    1.算法描述支持向量机(supportvectormachines,SVM)是二分类算法,所谓二分类即把具有多个特性(属性)的数据分为两类,目前主流机器学习算法中,神经网络等其他机器学习模型已经能......
  • m基于分段蚁群算法优化SVM的数据预测matlab仿真
    1.算法描述       支持向量机(supportvectormachines,SVM)是二分类算法,所谓二分类即把具有多个特性(属性)的数据分为两类,目前主流机器学习算法中,神经网络等其他机器......
  • 知识图谱推荐算法-基于嵌入的推荐方法
    基于嵌入的方法使用知识图谱中的信息来丰富用户或项目的表示,通过知识图谱嵌入将知识图谱中的实体和关系表征为低维向量,保留了知识图谱原有的结构。知识图谱通常存在链......
  • go语言int64整型转字符串
    go语言中string(int)会把int当成UTF-8的Unicode值,转换成对应的字符,标准库strconv是专门用来实现基本数据类型和其字符串表示的相互转换。packagemainimport( "fmt" "s......
  • HJ29_字符串加解密_模拟
    思路:根据加解密规则,使字符串加解密后输出。这是初始理解,编码起来较麻烦。查看高赞题解后,学到一种新思路关于加解密:最佳方法是通过通过设计加解密表,代码比较简单,通过列表in......
  • 2022牛客寒假算法基础集训营2 签到题7题
    1、C小沙的杀球如果你能够杀球但不杀球,虽然回复了体力,但你后续可能会没有机会继续杀球,并且杀球次数相同,那么回复的体力是相同的,所以在同等条件下,我们应该尽可能多的杀球。......