KMP算法
来源:互联网 发布:淘宝花草茶 那么便宜 编辑:程序博客网 时间:2024/06/05 11:51
KMP算法
什么是KMP算法
- KMP算法是一种改进的单字符串匹配算法。
- 全名:克努特—莫里斯—普拉特操作(简称KMP算法)
- KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。
- 具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。
KMP算法的实例
- 有这样一个字符串:BBC ABCDAB ABCDABCDABDE
- 我想知道,里面是否包含另一个字符串:ABCDABD?
KMP算法的思路
- 首先,字符串"BBC ABCDAB ABCDABCDABDE"的第一个字符与搜索词"ABCDABD"的第一个字符,进行比较。
- 因为B与A不匹配,所以搜索词后移一位。
- 因为B与A不匹配,搜索词再往后移就这样,直到字符串有一个字符,与搜索词的第一个字符相同为止。
- 接着比较字符串和搜索词的下一个字符.还是相同。
- 直到字符串有一个字符,与搜索词对应的字符不相同为止。
- 这时,最自然的反应是,将搜索词整个后移一位,再从头逐个比较。
- 这样做虽然可行,但是效率很差,因为你要把"搜索位置"移到已经比较过的位置,重比一遍。
- 那么我们想什么办法来解决这一问题呢?
- 一个基本事实是,当空格与D不匹配时,你其实知道前面六个字符是"ABCDAB"。
- KMP算法的想法是,设法利用这个已知信息,不要把"搜索位置"移回已经比较过的位置,继续把它向后移,这样就提高了效率。
- 可以针对搜索词,算出一张《NEXT值表》,即失败指针。这张表是如何产生的,等下再介绍,这里只要会用就可以了。
- 已知空格与D不匹配时,前面六个字符"ABCDAB"是匹配的。
- 查表可知,字符D对应的“NEXT值"为2,因此按照下面的公式算出向后移动的位数:
- 移动位数 = 已匹配的字符数 - 对应的NEXT值
- 因为 6 - 2 等于4,所以将搜索词向后移动4位。
- 因为空格与C不匹配,搜索词还要继续往后移。这时,已匹配的字符数为2("AB"),C对应的“NEXT值"为0。所以,移动位数 = 2 - 0,结果为 2,于是将搜索词向后移2位。
- 因为空格与A不匹配,0-(-1)=1,所以继续后移一位。
- 逐位比较,直到发现C与D不匹配。
- 于是,移动位数 = 6 - 2,继续将搜索词向后移动4位。
- 逐位比较,直到搜索词的最后一位,发现完全匹配,于是搜索完成。如果还要继续搜索(即找出全部匹配),移动位数 = 7 - 0,再将搜索词向后移动7位,这里就不再重复了。
- 下面介绍《NEXT值表》是如何产生的。
- 第一位的next值必定为-1;
- 计算第n个字符的NEXT值:
- 查看第n-1个字符对应NEXT值,设为a;
- 判断a是否为-1,若为-1,则第n个字符next值为0
- 若不为-1,将第n-1个字符与第a个字符比较
- 如果相同,第n个字符对应的NEXT值为a+1
- 如果不同,令a等于第a个字符的NEXT值,执行第第2步。
KMP模板代码
#include <stdio.h>#include <string.h>using namespace std;int next[10001];char str0[1000001];char str1[10001];void get_next(char *s){ int i=0,j=-1; next[0]=-1; int len=strlen(s); while(i<len) { if(j==-1 || s[i]==s[j]) { i++; j++; next[i]=j; } else j=next[j]; }}int kmp(char *s,char *t){ int len1=strlen(s),len2=strlen(t); int i=0,j=0,cnt=0; while(i<len1) { if(j==-1 ||s[i]==t[j]) { i++; j++; } else j=next[j]; if(j==len2) { cnt++; j=next[j]; } } return cnt;}int main(){ int n; scanf("%d\n",&n); while(n--) { gets(str1); gets(str0); get_next(str1); printf("%d\n",kmp(str0,str1)); } return 0;}
1 0
- KMP算法详解 【KMP】
- 【KMP】KMP算法模板
- KMP hihoCoder1015 KMP算法
- kmp算法
- KMP算法
- KMP算法
- KMP算法
- KMP算法
- KMP 算法
- kmp算法
- KMP算法
- kmp算法
- KMP算法
- KMP算法
- kmp算法
- kmp算法
- KMP算法
- KMP算法
- gradle 配置文件 build.gradle 属性详解
- coj 1343: Long Long
- DOM总结
- mybatis快速入门
- 类初始化与类对象初始化
- KMP算法
- 可以直接使用十六进制设置控件的颜色,而不必通过除以255.0进行转换
- 126. Word Ladder II
- 多线程造成死锁的例子
- 用javascript语言编写一个小程序:在一个文本框(用户名框)中按回车键时,跳转到另一个文本框(密码框)中,密码框回车之后,打一个登陆成功。点击button也是登陆成功。
- coj 1344: Special Judge
- Java中的编译时多态和运行时多态
- 继承的学习(8.13)
- 详解javascript中的this指针