KMP算法学习
来源:互联网 发布:手机淘宝开店我是卖家 编辑:程序博客网 时间:2024/06/03 20:07
1. KMP算法简介
KMP算法,是由Knuth,Morris,Pratt共同提出的模式匹配算法,其对于任何模式和目标序列,都可以在线性时间内完成匹配查找,而不会发生退化,是一个非常优秀的模式匹配算法。
2. 朴素的匹配算法
在介绍KMP算法之前我们来看看那朴素的匹配算法。定义:我们是在主串中搜索模式串。如下图当主串在e的位置与模式串发生失配时(e前面的都是匹配的),朴素的匹配算法做的是,将模式串后移一位在去匹。我们可以思考这样做是否有意义,因为模式串c前面是与主串匹配的,我们将模式串向后移动一位,与其自身对比,显然是无法匹中的,那么与主串肯定也是无法匹配的。那么应该移动多少位合适呢,这就是KMP算法讨论的问题。
3. Kmp算法详解
KMP算法主要为每个字符建立一个跳转表,通常用next数组来表示。next[j]=k的含义是,当主串中第i个元素与模式串中的第j个元素不匹配时,,我们应当保持i指针不动,而将模式串中的下标为k的元素与主串中的下标为i的元素对齐。
简单的解释是:当模式串中第j个元素与主串匹不中时,应该跳转到第k个元素与主串去匹配。
Next数组的构造是kmp算法的核心。
KMP next数组的构造:
根据定义next[0]=-1,假设next[j]=k, 即P[0...k-1]==P[j-k,j-1](1)
1)若P[j]==P[k],则有P[0..k]==P[j-k+1,j],很显然,next[j+1]=next[j]+1=k+1;
2)若P[j]!=P[k],则可以把其看做模式匹配的问题,即匹配失败的时候,k值如何移动,显然k=next[k]。
1) 显然,关键是2),2)的证明如下:
因为 next[j]=k
则:p[0….k-1] =p[j-k…..j-1]
又P[j]!=P[k]
则下面的任务是要找
P[0..k’] 是否有等于 p[j-k’..j]的 k’<k
因为 p[j-k’…j-1]= p[ k-k’…k-1]
因此只要检查是否存在k’使得 p[0..k’-1]= p[ k-k’…k-1] (2)并且p[k’]=p[j]
若存在则,next[j]=k’
比较(1) (2)两式可得 k’=next[k]
即:next[j]=next[next[j-1]
若p[k’]=p[j]还不相等,接着迭代
4.kmp算法测试程序
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
voidmakenext(const char c[],int *next)
{
int i=0,k=-1;
next[0]=-1;
int ilen = strlen(c);
while(i<ilen)
{
while(k>=0&&c[i]!=c[k])
k = next[k];
i++;k++;
next[i] = k;
}
}
intKMPsearch(const char *pstrObj,const char *pstrPattern)
{
int iobjlen,ipatternlen;
iobjlen = strlen(pstrObj);
ipatternlen = strlen(pstrPattern);
int next[iobjlen];
makenext(pstrPattern,next);
int i=0,j=0;
while(j<ipatternlen&&i<iobjlen)
{
if(j==-1||pstrPattern[j] ==pstrObj[i])
{
i++;
j++;
}
else
{
j=next[j];
}
}
if(j==ipatternlen)
{
return (i-ipatternlen);
}
else
{
return -1;
}
}
int main()
{
char str[20]="cfababacfgf";
char pattern[10] = "ababac";
int iStart;
iStart = KMPsearch(str,pattern);
if(iStart == -1)
{
printf("NOT FOUND!\n");
}
else
{
printf("finded, Obj stringPos:%d\n",iStart);
}
}
- KMP算法知识学习
- KMP算法学习
- KMP算法学习笔记
- KMP算法学习
- KMP算法学习
- KMP算法学习!
- KMP算法学习总结
- KMP算法学习
- KMP算法学习
- 初步学习KMP算法
- KMP算法学习
- KMP算法学习
- KMP算法学习
- KMP 算法学习
- 学习笔记-KMP算法
- KMP算法 学习笔记
- Kmp算法学习笔记
- KMP算法学习&总结
- MDX和SQL区别
- java 类的方法调用
- Linux 常用命令
- 泛型
- MYSQL的一些使用总结
- KMP算法学习
- hibernate简介
- python向已有文档中加入字符串
- EM算法
- .bash_profile和.bashrc的区别及启动过程
- 上班那些事儿之六月
- 基于状态机的游戏框架
- 多线程执行顺序
- 最简单的对话中弹出对话框