next[i]:求模式串中前缀和后缀的最长公共前缀
即对于[1,i]来说,求最大的x,使s[1,x]等于s[i-x+1,i]
以hdu1711为例,
统计a串中第一个出现b串的起始下标,
即若第一个出现b串的区间是[l,r],输出l
#include
#include
#include
using namespace std;
int a[1000005],b[10005];
int n,m;
int nex[10005];
void kmppre(){int i=0,j=nex[0]=-1;while(i
最小表示法:
对于串bca来说,其循环串abc,bca,cab中字典序最小的那个,串abc,即为最小表示
最大表示法同理
hdu3374,用kmp求一个串的最小表示法
//一个串在表示法里出现了几次 等于这个串的循环节在串中出现的次数
//考虑一串珠子 往后转循环节个长度 还能得到一个与原串相同的串 这就是循环节的定义
//即循环节出现的次数 即为表示法中出现的次数
#include
#include
#include
#include
#include
#include
#include
#include
next[i]:求模式串中前缀和后缀的最长公共前缀
即对于[1,i]来说,求最大的x,使s[1,x]等于s[i-x+1,i]
extend[i]: 求文本串中以i开始的一个后缀,和模式串中的前缀的最长公共前缀
即,对于文本串t[1,m]和模式串s[1,n]来说,
求最大的x,使得t[i,i+x-1]等于s[1,x]
kmp可以取巧替代exkmp,并且实际效果比kmp快
令t=s+'#'+t,即模式串在最前,中间用未出现的字符分隔,文本串在最后
则数组后半部分的next[i]即为所求
以poj3080为例,
多个字符串,问你这几个字符串的最长公共子串是哪个,
如果有多个,输出字典序最大的那个,
如果最长的公共子串长度小于3,输出no significant commonalities
其实有点强行用exkmp的意思,暴力枚举每个串判是否在其他的串中存在,kmp也可以
#include
#include
#include
#include
#include
#include
#define sci(x) scanf("%d",&(x))
#define scs(x) scanf("%s",(x))
#define scll(x) scanf("%lld",&(x))
#define sclf(x) scanf("%lf",&(x))
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
char a[15][65];
int net[65],ex[65];
char s1[65],s2[65],tmp[65];
void extkmppre(char s[])
{int i=0,j,pos,len=strlen(s);net[0]=len;while(i+1maxlen){maxlen=j-i+1;l=i,r=j;}else if(j-i+1==maxlen){rep(k,0,maxlen-1){if(a[0][k+i]>a[0][k+l])break;if(a[0][k+i]