KMP算法及POJ上相关的题目
来源:互联网 发布:mac重装系统全盘格式化 编辑:程序博客网 时间:2024/06/05 11:37
KMP算法的介绍与POJ上一些相关的题目
一 :KMP算法的介绍
KMP算法的核心是构造next[]数组。先搞清楚next数组的含义。例如:next[j] = k;这样的一个式子表示的含义是:当主串中第i个元素与模式串中的第j个元素匹配失败时,应该保持i指针不动,而将模式串中的j指针移动到k这个位置。然后将主串中第i个元素与模式串中的第j个元素匹配。若匹配的话就同时移动i和j指针。不匹配的话,再次计算next[k] = ?.....依次进行。
所以KMP算法的本质就是主串中i指针不回溯。
下面来一步步的证明next[]数组的构造过程。
第一步:
设主串S = “s1s2…sn”, T= “t1t2…tm”.
若满足:
(1) “si-j+1…si-1” = “t1..tj-1”;
(2) “t1t2…tk-1”= “tj-k+1tj-k+1…tj-1”;(1<k<j)
在同时满足(1),(2)的条件下,可以直接比较si 和 tk;
若对于任意的1<k<j,条件(2)都不满足,则直接比较si和t1;
第二步:
模式串t的next函数:
当si 和tj 匹配失败时,si与tnext(j) 匹配。
第三步:
求 next()函数的算法:因为已知next(0) = -1,只要找出next(j+1)与next(j)之间的关系,就可以求出所有的next(j).
初始算法:
(1) 初值next(0) = -1;
(2) 设next(j) = k, 说明“t1t2…tk-1”= “tj-k+1tj-k+1…tj-1”;(1<k<j)
(2-1) 若tj = tk, 则有“t1t2…tk-1tk” = “tj-k+1tj-k+1…tj-1tj”; (1<k<j)
所以next(j+1) = next(j) + 1 = k + 1;
(2-2)若tj tk,因为有next(k) = k’,
则必然有:“t1t2…tk’-1”= “tj-k’+1…tj-1”;
(2-2-1) 若tj = tk’,则next(j+1) =next(next(j)) + 1 = k’+ 1;
(2-2-2)若tj tk’ ,则重复(2-2).直到不存在K(n),则next(j+1)=0;
第四步:
求next函数算法:
void get_next(sstring T, int &next[])
{
//求模式串T的next函数值并存入数组next。
j=1; k=next[j]=0;
while (j<T[0]) //计算next(j)从next(2)到next(T[0]),T[0]是T的长度
//但并不意味着只循环m-1次,因为在循环体中j的值可能不发生变化
if (k==0||T[j]==T[k])// 没有重叠真子串和(有重叠真子串但T[j]==T[k])时
//都应该得出next(j+1)的值
next[++j]=++k;//书上:{++j ; ++k;next[j]=k;}
else k=next(k);//否则,得不出next(j+1)的值,所以j不变,k退回到next(k),重复匹配。
}//end ofget_next
二:POJ上一些相关的题目
由于初学KMP,所以做的都是一些比较简单的题目。
(参考博客:http://blog.csdn.net/lalor/article/details/7358956)
1. POJ 3461 http://poj.org/problem?id=3461
题意:求模式串在主串中出现的次数。当匹配一次成功的时候,假设最后一个字符没有匹配成功,则j=next[j];所以只需把匹配的过程稍微改变一下即可。
2: POJ 2752 http://poj.org/problem?id=2752
题意:求给定串中所有前缀和后缀相等的情况。
假设当前j指针指向最后一个字符,next(j)= j’ ,所以3-1区间与4-5区间相同。
接着next(j’) = j’’,所以①与②区间相同。假设存在一个点,把4-5区间分成了③,④。因为①+②与③+④相同,所以③与④相同,所以①与④相同。
3.POJ 2406 http://poj.org/problem?id=2406
题意:求给定串中重复串的个数。
用到了:if(len %(len – next[len])== 0) ans = len / (len – next[len]);
不会证明。
4.POJ 1961 http://poj.org/problem?id=1961
题意:求给定串中所有前缀的重复串的个数。
与上一题一样的思路。
- KMP算法及POJ上相关的题目
- 本机上相关字符类型的字节数
- Mac上相关安装和一些命令的使用
- 日积月累:Linux上相关su和sudo的命令和技巧
- poj KMP题目总汇
- 其他题目---KMP算法
- poj题目详细分类及算法推荐题目
- poj 1961 KMP算法的应用
- Period poj 1961 KMP算法的运用
- poj(2185) Milking Grid (很好的kmp题目)
- poj 2752 kmp算法
- poj 2406 KMP算法
- POJ 3461 KMP算法
- poj 3461 kmp算法
- KMP及KMP改进算法
- 杭电 KMP算法题目
- KMP算法的原理及实现
- KMP算法及相关问题的总结
- SQL语句
- 矩阵 Hessian
- CA
- C socket
- 讲字符串按照字节截取 JAVA
- KMP算法及POJ上相关的题目
- 百度地图API学习
- android平台下使用点九PNG技术
- php中argc和argv的用法
- 苹果机操作
- LR监控Windows性能(包含虚拟机)
- 黑马程序员——java第七天:面向对象(继承、子父类之变量、final、抽象、模板方法、接口)
- 敏捷开发--scrum
- java垃圾回收机制剖析