KMP算法学习笔记

来源:互联网 发布:淘宝如何代理虚拟 编辑:程序博客网 时间:2024/06/04 18:57

先有一个流程的感受(http://kb.cnblogs.com/page/176818/)此处的讲解特别易懂!

"部分匹配值"就是"前缀"和"后缀"的最长的共有元素的长度。以"ABCDABD"为例,
- "A"的前缀和后缀都为空集,共有元素的长度为0;

- "AB"的前缀为[A],后缀为[B],共有元素的长度为0;

- "ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;

- "ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;

- "ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为1;

- "ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB",长度为2;

- "ABCDABD"的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。

有了直观感受下面正式介绍KMP算法

1.简介

一种改进的字符串匹配算法,由D.E.Knuth与V.R.Pratt和J.H.Morris同时发现,因此称之为KMP算法。此算法可以在O(n+m)的时间数量级上完成串的模式匹配操作,其基本思想是:每当匹配过程中出现字符串比较不等时,不需回溯指针,而是利用已经得到的“部分匹配”结果将模式向右“滑动”尽可能远的一段距离,继续进行比较。

2.next特征数组构造

特征数ni ( -1≤ ni ≤ i )是递归定义的,定义如下:
   (1) n[0] = -1,对于i > 0的n[i] ,假定已知前一位置的特征数 n[i-1]= k ;
   (2) 如果pi = pk ,则n[i] = k+1 ;
   (3) 当pi ≠ pk 且k≠0时,则令k = n [k -1] ; 让(3)循环直到条件不满足;
   (4) 当qi ≠ qk 且k = 0时,则ni = 0;

求解代码:

void get_next() {    int l = strlen(w);    int i,j;    i=0,j=-1,next[0]=-1;    while(i<l) {        if(j==-1 || w[i]==w[j]) {            i++;            j++;            next[i] = j;        }         else    j=next[j];    }}
3.模式匹配

int kmp() {    int l2 = strlen(w),l1 = strlen(t);    int i=0,j=0,s=0;    while(i<l1) {        if(j == -1||w[j]==t[i]) {            i++;            j++;        }         else j=next[j];        if(j>=l2) {            j=next[j];               //关键            s++;        }    }    return s;}



0 0
原创粉丝点击