上周挖的坑,没想出来,看题解完全不知道在说啥,自己瞎琢磨了下,胡乱设计了个KMP的算法
只知道题解说要构造我就乱构造,乱写就A了。。。
一道非常不错的KMP的题
第一大难点就是要想到去构造
第二大难点就是怎么去构造
第三大难点是构造出来的串需要满足能恰好匹配到末尾,所以要解决这个问题
关键是第三个,解决办法见代码最后一个else那里和return的值
KMP写挫了一次,害我查半天
//#define _TEST _TEST
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/************************************************
Code By willinglive Blog:http://willinglive.cf
************************************************/
#define rep(i,l,r) for(int i=(l),___t=(r);i<=___t;i++)
#define per(i,r,l) for(int i=(r),___t=(l);i>=___t;i--)
#define MS(arr,x) memset(arr,x,sizeof(arr))
#define LL long long
#define INE(i,u,e) for(int i=head[u];~i;i=e[i].next)
inline const int read()
{int r=0,k=1;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')k=-1;
for(;c>='0'&&c<='9';c=getchar())r=r*10+c-'0';return k*r;}
/////////////////////////////////////////////////
char s[1000010];
char ss[1000010];
int n,m;
int next[1000010];
int T;
/////////////////////////////////////////////////
void add(char c)
{
int j=next[m];
while(j&&ss[j+1]!=c) j=next[j];
j+=ss[j+1]==c;
next[++m]=j;
ss[m]=c;
}
int get_next()
{
int j=0,cur=1,pos=0;
ss[1]=s[1]; next[1]=0;
rep(i,2,n)
{
bool last=cur==m;
while(cur && (cur>=m || ss[cur+1]!=s[i])) cur=next[cur];
if(last&&ss[cur+1]!=s[i]) add(s[i]),cur=m;
else if(ss[cur+1]==s[i]) cur++;
else
{
rep(j,pos+1,i) add(s[j]);
cur=m;
}
if(cur==m) pos=i;
/*printf("%d\n",i);
printf("%s\n",ss+1);
rep(i,1,m) printf("%d ",next[i]); puts("\n");*/
}
return m+n-pos;
}
/////////////////////////////////////////////////
void input()
{
T++;
scanf("%s",s+1);
n=strlen(s+1); m=1;
}
void solve()
{
printf("Case %d: %d\n",T,get_next());
}
/////////////////////////////////////////////////
int main()
{
#ifndef _TEST
freopen("std.in","r",stdin); freopen("std.out","w",stdout);
#endif
rep(i,1,read())
input(),solve();
return 0;
}

本文分享了一道关于KMP算法的难题解决方案,重点介绍了如何构造字符串以实现精确匹配,并通过具体代码展示了KMP算法的实现细节。

612

被折叠的 条评论
为什么被折叠?



