KMP的一些总结

小结论:

nxt[x]表示前0~x-1位存在的最长前缀=后缀的长度.

一个字符串长度为m, 那么最小循环节长度为m-nxt[m]

s串任意前缀的nxt数组就是s串的nxt数组, 直接用就行了

kmp的小技巧:

如果只看s中有没有t,kmp()循环加上当j==m时break的条件.

如果求出现次数, 要去掉①中的条件, 并每当j==m(匹配成功)时, 把j赋为nxt[j]

如果求不重复的次数, 要去掉①中的条件, 并每当j==m(匹配成功)时, 把j赋为0(不再按kmp匹配, 直接将模式串头部移到下一位)

关于nxt数组的小技巧:

s串后面最少加几个能成循环串

如果最小循环节长度x=0, 那么就要加一倍

如果|s|%x=0, 他已经是循环串了, 不用再加

|s|%x≠0, 缺多少补多少

对于s的所有前缀, 前缀i是不是由某个串重复k(k>1)次构成

对于每个长度为pos的前缀, 求其最小循环节长度x, 若pos%x=0且pos/x>1那么这个0~pos-1的前缀就是合法的.

给出串t, 问它最多能由多少个s构成, s为任意大小.

至少是1, s为t本身, 如果更短的s合法, 他一定是某个更长的s的一部分.

只要不断求当前串的最小循环节x, 若|t|%|x|==0就继续求nxt[x], 如果当前串不合法, 它的儿子更不可能合法.

求串S的所有既是前缀又是后缀的字串长度.

若A是S的前缀&后缀, B是A的前缀&后缀, 那么B也会是S的前缀后缀.

用nxt[]即可求.

给出S和T, 求最长的X, 既是S的前缀又是T的后缀.

S+T求nxt[len]是不行的, X可能会越过连接处.

S+'@'+T, 用特殊字符分隔即可.

每个前缀出现次数的和.

cnt[pos]记录第pos个前缀x在比他长的前缀y中出现的次数,

递推式:cnt[nxt[a]]+=cnt[a]+1

定义原串的前缀为x类串.

每个长度为a的x类串s会包含2个长度为nxt[a]的x类串t, 而两个相邻的s会有一个重复的t, 所以cnt[a]个s会有cnt[a]+1个t.

最后答案加上每个前缀本身共m. 具体见代码.

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值