KMP算法

注意:以下所有string都是从0开始的

一、功能

求出子串T在字符串S中各次出现的位置

二、性质

最小周期长度:len(S) - next[ len(S) - 1 ];

例如:
“abb”最小周期长度 = 3 – next[2] = 3
“abba”最小周期长度 = 4 – next[3] = 3

三、思路

①next[ i ]:表示第 i 位的最长公共前后缀长度

next的求法:
如果已知next[0] ~ next[i - 1]
令j = next[i – 1],如果s[ i ] = s[ j ],那么j++,next[i] = j ,否则令j = next[ j ],继续之前的操作
若j = 0时依旧无法匹配,那么next[i] = 0

②将S和T合成一个串P=T+'#'+S,对P求next数组

③对于所有的i,满足next[i] = len(T),那么i – 2len(T)便是T在S中出现的初始位置(从0开始)

四、代码

#include<bits/stdc++.h>
using namespace std;
const int MAX=1000005;
string s,t,p;
int lens,lent,lenp;
int nxt[MAX*2];//别忘*2,因为两个串要合并
void kmp_nxt()//求next数组
{
	lenp=p.length(), lens=s.length(), lent=t.length();
	nxt[0] = 0;
	for(int i=1; i<=lenp-1; ++i)
	{
		int j = nxt[i-1];
		while(j>0 && p[i]!=p[j])
			j = nxt[j-1];
		if(p[i] == p[j]) j++;
		nxt[i] = j;
	}
}
int main()
{
	cin>>s>>t;
	p = t+'#'+s;
	kmp_nxt();
	for(int i=lent+1; i<lenp; ++i)
		if(nxt[i] == lent)
			printf("%d\n",i-2*lent+1);
	for(int i=0; i<=lent-1; ++i)
		printf("%d ",nxt[i]);
	return 0;
}
/*
ABABABC
ABA
A B A # A B A B A B C
0 0 1 0 1 2 3 2 3 2 0
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值