KMP专题

第一题 hdu 1711 Number Sequence

点击打开hdu 1711

思路:

1 kmp是用来匹配字符串,只能够匹配单一的字符串
2 kmp的算法的过程:
  1:假设文本串的长度为n,模式串的长度为m;
  2:先例用O(m)的时间去预处理next数组,next数组的意思指的是当前的字符串匹配失败后要转到的下一个状态;
  3:利用o(n)的时间去完成匹配;

3 时间复杂度为o(n+m)即o(n);

点击查看代码

 

第二题 hdu 1686 oulipo

点击打开hdu 1686

思路:

1 题目要求的是给定一个模式串个一个文本串,求出模式串在文本串中出现几次
2 典型的KMP问题,只要套上模板即可。

点击查看代码

 

第三题 hdu 2087 剪花布条

点击打开hdu 2087

思路:

1 题目要求的是给定一个文本串和给定一个模式串,求文本串中有几个模式串。
2 注意文本串为"aaaaaa",模式串"aa"的时候,ans = 3 而不是5。

点击查看代码

 

第四题 hdu 3746 Cyclic Nacklace

点击打开hdu 3746

思路:

1 题目要求的是给定一个字符串,问我们还需要添加几个字符可以构成一个由n个循环节组成的字符串。
2 可知我们应该先求出字符串的最小循环节的长度:假设字符串的长度为len,那么最小的循环节就是cir = len-next[len] ; 如果有len%cir == 0,那么这个字符串就是已经是完美的字符串,不用添加任何字符;如果不是完美的那么需要添加的字符数就是cir - (len-(len/cir)*cir)),相当与需要在最后一个循环节上面添加几个。
3 如果cir = 1,说明字符串只有一种字符例如“aaa” ; 如果cir = m说明最小的循环节长度为m,那么至少还需m个;如果m%cir == 0,说明已经不用添加了

点击查看代码

 

第五题 hdu 1358 Period

点击打开hdu 1358

思路:

1 题目要求的是给定一个长度为n的字符串,求出字符串的所有前缀字符串中该字符串刚好由k个最小循环节够成,由于题目要求k最大那么就是这个循环节最小
2 只要先求出next数组,然后去枚举所有的前缀找到满足的输出长度和k

点击查看代码

 

第六题 hdu 2203 亲和串

点击打开hdu 2203

思路:

1 题目要求的是给定字符串s1 和 s2,问s1能否通过移位得到使得s2包含在s1里面。
2 很显然的kmp的模板题,只须在s1后面在添上一个s1即可。

点击查看代码

 

第七题 poj 2406 Power Strings

点击打开poj 2406

思路:

1 题目要求的是给定一个字符串找到最小循环节的个数,但是这里有个限制的地方就是如果这个字符串不是刚好由n个最小循环节组成那么就认为一整串才是一个循环节

点击查看代码

 

第八题 poj 2752 Seek the Name, Seek the Fame

点击打开poj 2752

思路:

1 题意要求的找出满足既是字符串的s的前缀又是后缀的字串输出该字串的长度。
2 先看看next数组的含义:
   1:next数组只和模式串本身有关和文本串是无关的,因为next表示的是当匹配失败后模式串要回溯到哪个位置。
   2:next数组存储的数据是用来当模式串与主串不匹配的时候要模式串回退到第几个字符与主串再重新匹配,我们知道KMP算法的主串是不回朔的,当不匹配的时候我们不是退回到开始位置重新匹配,而是利用已经匹配的结果将模式串回朔到下一个位置,这个位置比开始位置更近一步;
简单的说就是next[ j ]的值保存的是当模式串中第 j 个字符与主串第 i 个字符不匹配时候,模式串中的哪个字符 重新与主串第 i 个再匹配,这样总的字符比较次数比从开始位置比较的次数就少了。
   3:next[j]存储的就是模式串前j个字符里前缀和后缀最大的匹配长度;也就是有j = next[j] ; 假设有模式串“abcabx”,那么next[5] = 2就是前5个字符里前缀和后缀匹配最长的长度为2即“ab”;那么就是说如果next[len] = ans , 整个串的前缀和后缀最长匹配的长度就是ans,上面的字符串“abcabx”的最长匹配就是0。
   4:在模式串与标准串进行匹配时,指向他们的指针分别为j、i;当p[j]!=s[i]时,j直接变为next[j],新的p[j]继续与s[i]比较,如果不相等继续进行此操作……那么数组next[j]同样反映了,在模式串p的第j个位置之前,p[0]~p[next[j]-1]与p[i-next[j]]~p[i-1]这两段是完全一样的。假设模式串为“abcdabx”,手动模拟即可知道。

点击查看代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值