kmp算法是用来对字符串进行匹配的一种算法。对于长度为n的字符串N,要查找其中长度为m的一个字符串M,传统的暴力方法的复杂度为O( nm ),而用kmp算法时间复杂度为O( m+n )。*
所谓KMP最重要的就是next[]数组 他表示的意思是 在当前下标i下 最长的前缀和后缀相等的长度
这里的下表要与字符串下标区分开
例如 abcabc 初始next[0]=-1;
next[1]=0; next[2]=0; next[3]=0; 到第四个字母位置时末尾a 和 开端a相等所以next[4]=1; 又因为b和b相等 所以next[5]=2;
然后紧接着 c和c相等 next[6]=3;
例如 abcababc
next[0]=-1; next[1]=0; next[2]=0; next[3]=0; next[4]=1; next[5]=2; next[6]=1; next[7]=2; next[8]=3;
那如何计算的呢
如果一直相等 就一直递增 否则就重置一下
计算得到next数组
然后在主串中找子串的时候 就可以利用next数组来大大的优化,根据相同的前缀后缀可以省略很多比较
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
const int maxn=1e6+88;
ll nex[maxn];
void slu(string s){
int i=0,k=-1;
nex[0]=-1;
while(i<s.size())
{
if(k==-1|| s[i]==s[k] ){
i++;
k++;
nex[i]=k;
}
else{
k=nex[k];
}
}
}
void kmp(string s1,string s2){
int l1=s1.size(),l2=s2.size();
int i=0,j=0;
while(i<l1&&j<l2){
if(j==-1||s1[i]==s2[j]){
j++;
i++;
if(j==l2)
{
cout<<"YES";
return;
}
}else{
j=nex[j];
}
}
cout<<"NO";
}
int main(){
string s1,s2;
cin>>s1>>s2;
slu(s2);
for(int i=0;i<=s1.size();i++){
cout<<nex[i]<<endl;
}
kmp(s1,s2);
return 0;
}
输入描述:
输出描述:
Your program is to write to standard output. Print two integers k and p in one line.
The following shows sample input and output for two test cases.
链接:https://ac.nowcoder.com/acm/contest/13506/I
来源:牛客网
输入
复制
6
612534 3157 423 3157 423 3157
输出
复制
1 2
示例2
输入
复制
9
1 2 1 3 1 2 1 3 1
输出
复制
0 4
本质求周期,将数字当成字符来看 即可 套kmp模板
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
const int maxn=1e6+88;
//char s1[maxn];
ll s2[maxn];
ll nex[maxn];
void slu(){
int i=0,k=-1;
nex[0]=-1;
while(i<n)
{
if(k==-1|| s2[i]==s2[k] ){
i++;
k++;
nex[i]=k;
}
else{
k=nex[k];
}
}
}
/*void kmp(){
int l1=strlen(s1),l2=strlen(s2);
int i=0,j=0;
while(i<l1&&j<l2){
if(j==-1||s1[i]==s2[j]){
j++;
i++;
if(j==l2)
{
cout<<i-l2+1<<endl;
return;
}
}else{
j=nex[j];
}
}
cout<<0<<endl;
}*/
int main(){
scanf("%d",&n);
for(int i=n-1;i>=0;i--)
{
scanf("%d",&s2[i]);
}
slu();
ll sum=1999999999;
ll k,p;
for(int i=n;i>=1;i--)
{
int tk=n-i;
int tp=i-nex[i];
if(tk+tp<sum||(tk+tp==sum&&tp<p)){
sum=tk+tp;
p=tp;
k=tk;
}
}
cout<<k<<' '<<p;
return 0;
}