KMP 算法简述
来源:互联网 发布:下载烈火软件 编辑:程序博客网 时间:2024/06/04 19:34
kmp算法是一个比较经典的字符串比较算法,现在学渣准备用最贴地气的方法简述一下,希望和大家共同学习。
1 字符串比较
在本文中,主要用如图1的两个字符串进行比较。这是算法导论里的例子,上面的字符串我们称为T,下面的成为模式P
图1 图2
如图1所示,如果在比较到绿线所指的a和c时,发现两个字母不匹配,如果在朴素算法中,需要将P右移一位,重新进行对比,如图2
2规律
其实在这个匹配过程中,有一部分信息被丢掉了,因为如图1,T和P的红框部分的ababa已经完全匹配,完全可以向后移动3位,如图3所示,进行比较
这时发现,从这个位置开始比也是完全可行的,如果按照朴素算法,向后移动一位发现不匹配,再向后移动,会消耗大量的时间。
图3
3 前缀函数
如上所述,在字符串的匹配过程中,如何才能预知以上的这种规律呢,就是前缀函数,算法导论里叫π。在字符串的匹配过程中,模式P是提前预知的,于是我们讲对P进行惨无人道的压榨,获取其的一些信息用来组成π。
我们需要对2中的规律进行详细分析,我们需要的是神马规律,对于T而言,如果在判断到T[i]与P[q]时,两个元素不等时,我们需要一个信号,即这个T[i]和P的哪个元素相比较才是又快捷又不会丢失信息呢?例子中的a需要和P的第4个元素进行对比(我们假设这个数组从第1个元素开始),即我们认为我们已经重新匹配了P的三个元素了,我们只需要从第四个元素开始比较就行。因为我们已经对P进行了分析,那么我们可以定义一个数组(就是π),如现在我在图1中匹配了5个字母,我在π[5]中放一个3,代表如果T中的任何一部分能够和P的前5个元素进行匹配 ,如果第六个不匹配时,只需要匹配第π[5]+1个元素就ok,π[i]的意义就是,如果前i个元素都匹配,第i+1个元素不匹配,只需要用第π[i]个元素进行对比。例子中的是P的前3个元素和ababa的后三个元素完全匹配,用算法导论里的书面语言就是:P3是能构成P5的真后缀的P的最长前缀(学渣用了好几分钟才看懂这几个中国字。。。)
如果大家能看懂上述的描述,对于前缀数组π而言,π[i]的意义是,P(π[i]) 是能构成Pi 的真后缀的P的最长前缀。书面的表达式是:
π[q] = max {k: k < q 且 Pk < Pq} (第二个<是包含符,学渣表示不会打这个符号)
4 求前缀数组
对于π[1],一定等于0,一个元素没有前缀。。。
前缀数组是指模式P的前缀数组(重要。。。),算法如下:
p = P.length
π[1]=0; //第一个元素一定为0
k=0 //相当于两个P在对比,一个是从k开始,一个是从q开始,k代表已经匹配好的元素
for q=2 to m //直接从第二个元素开始计算
while k > 0 and P[k+1] != P[q] //最关键的一步如果第P[k+1] 和 P[q]不相等,则利用π的定义,而且前k个都已经匹配,π[k]代表用第π[k+1]个元素对比就行
k = π[k]
//到了此步的k,说明P[q]和P[k+1]是一定要进行对比的
if P[k+1] == P[q]
k=k+1
π[q] = k //
return π ....
- kmp算法简述
- KMP算法简述
- KMP算法简述
- KMP 算法简述
- 算法简述
- KMP算法详解 【KMP】
- 【KMP】KMP算法模板
- KMP hihoCoder1015 KMP算法
- kmp算法
- KMP算法
- KMP算法
- KMP算法
- KMP算法
- KMP 算法
- kmp算法
- KMP算法
- kmp算法
- KMP算法
- HDU 2066
- android键盘挡住界面
- C、C++、Java异或运算交换变量变量值的区别
- 数组循环移位算法
- apt-get的用法总结(持续更新)
- KMP 算法简述
- OCP-1Z0-051 第81题 SYSDATE函数
- android listview 异步加载图片并防止错位
- struts2多文件上传(修改名称、压缩图片、删除图片)
- 10个迷惑新手的Cocoa,Objective-c开发难点和问题
- 动态链接库和静态链接库的创建及应用实例
- C/C++学习
- 易触网的CSDN博客成立了
- eclipse svn插件的安装