Today , 第一次学习KMP Algorithm,其中好多地方还是不能理解的透彻,本文将进一步对 KMP Algorithm 进行学习,搞清楚其中的思想……

  First , KMP Algorithm is best known for liner time for exact matching ,  (Runing time is O(Length(S)+Lendth(P)))  Because Preprocessing is O(P) , Matching is O(Length(S)) , 效率很 high , 成功的避免了Recomputing Matches ;

    若想 Avoid Recomputing Matches , 就需要 Preprocessing ,对于 Preprocessing ,就是找出字符串P中的 Repeat char can backtrack position by prefix-function;

字符串P为:

a b a b a c a

字符串S为:

b a c b a b a b a b a c a a b

  定义两个指针 i 和 j ,i  是指向 字符串 S 中的第 i 个数据元素 , j 是指向字符串 P 中的第 j 个数据元素 ,用指针 i 和  j 分别表示 S[ i - j + 1 , …… i ] 和 P[ 1 , …… j ] 中的数据元素完全相等, 随着 i 的值不断增加 , j 的值也在不断变化 ,通过对字符串 P 进行 Preprocessing 得到 fail数组 ,j 的值变化有两种可能:1、如果 P[ j + 1 ] 与 S[ i + 1]相等,j 应该加 1 ; 2 、如果 P[ j + 1 ] 与 S[ i + 1 ] 不相等 ,则 j 应该等于 fail数组中第 j 个数据元素的值 ;fail数组就是用来记录 当P[i + 1] 与 S[ j + 1 ] 不相等时 , j 的变化 ;

下面介绍一下,Prefix - function ,即如何确定fail 数组 ;

m ← Length[ P ] ;

k = 0 ;

fail[0] ← 0 ;

for q ← 1 to m  do

  while k > 0 and p[k] ≠ p[q]  do

    k = next[k-1] ;

  end while

  if(p[k] = p[q] )

    k ← k + 1 ;

  end if

  next[q] = k ;

end for

这样即可得到 fail数组 ;  

得到 fail 数组之后,就可进行字符串P 与 字符串S 进行匹配了 ,具体匹配过程,下面给出相应的伪代码:

n ← Length[ S ]

m ← Length[ P ]

k = 0 ;

for i ← 0 to n  do

  while k > 0 and p[ k ] ≠  S[ i ]  do

    k = fail[ k -1] ;

  end while

  if p[k] = S[i]  then

    k ← k + 1

  end if

  if k == m then

    return i - m + 1

  end if

end for

return  -1

下面给出KMP算法的详细代码过程:

#include<iostream>
#include<string.h>
using namespace std ; int fail[1000] ; void prefix( char *p ) {
int len = strlen(p) ;
int k = 0 ;
fail[0] = 0 ;
for( int q = 1 ; q < len ; q++) {
while( k > 0 && p[k] != p[q] ) // K > 0 的原因是为了让后面的 s[q] 先和 s[0] 比较保证找到后面的能够出现和第一个相等 ;
k = fail[k-1] ;
if(p[k] == p[q])
k++ ;
fail[q] = k ;
}
} int kmp( char *s , char *p ) {
int len1 = strlen(s) , len2 = strlen(p) ;
int k = 0 ;
for(int q = 0 ; q < len1 ; q++ ) {
while( k > 0 && s[q] != p[k] ) // K > 0 为了保证后面的和第一个比较出现相等的 ;
k = fail[k-1] ;
if(s[q] == p[k])
k++ ;
if(k == len2)
return q - len2 + 1 ;
}
return -1 ;
} int main() {
char s[1000] , p[1000] ;
cin >> s >> p ;
prefix(p) ;
if(kmp(s,p) != -1)
cout << kmp(s,p) << endl ;
else
cout << "NO" << endl ;
return 0 ;
}

  

Knuth-Morris-Pratt Algorithm的更多相关文章

  1. 我所理解的 KMP(Knuth–Morris–Pratt) 算法

    假设要在 haystack 中匹配 needle . 要理解 KMP 先需要理解两个概念 proper prefix 和 proper suffix,由于找到没有合适的翻译,暂时分别称真实前缀 和 真 ...

  2. 字符串匹配算法--KMP字符串搜索(Knuth–Morris–Pratt string-searching)C语言实现与讲解

    一.前言   在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息 ...

  3. 笔试算法题(52):简介 - KMP算法(D.E. Knuth, J.H. Morris, V.R. Pratt Algorithm)

    议题:KMP算法(D.E. Knuth, J.H. Morris, V.R. Pratt Algorithm) 分析: KMP算法用于在一个主串中找出特定的字符或者模式串.现在假设主串为长度n的数组T ...

  4. Aho - Corasick string matching algorithm

    Aho - Corasick string matching algorithm 俗称:多模式匹配算法,它是对 Knuth - Morris - pratt algorithm (单模式匹配算法) 形 ...

  5. GO语言的开源库

    Indexes and search engines These sites provide indexes and search engines for Go packages: godoc.org ...

  6. Go语言(golang)开源项目大全

    转http://www.open-open.com/lib/view/open1396063913278.html内容目录Astronomy构建工具缓存云计算命令行选项解析器命令行工具压缩配置文件解析 ...

  7. 一个字符串搜索的Aho-Corasick算法

    Aho和Corasick对KMP算法(Knuth–Morris–Pratt algorithm)进行了改进,Aho-Corasick算法(Aho-Corasick algorithm)利用构建树,总时 ...

  8. [转]Go语言(golang)开源项目大全

    内容目录 Astronomy 构建工具 缓存 云计算 命令行选项解析器 命令行工具 压缩 配置文件解析器 控制台用户界面 加密 数据处理 数据结构 数据库和存储 开发工具 分布式/网格计算 文档 编辑 ...

  9. go语言项目汇总

    Horst Rutter edited this page 7 days ago · 529 revisions Indexes and search engines These sites prov ...

  10. Golang优秀开源项目汇总, 10大流行Go语言开源项目, golang 开源项目全集(golang/go/wiki/Projects), GitHub上优秀的Go开源项目

    Golang优秀开源项目汇总(持续更新...)我把这个汇总放在github上了, 后面更新也会在github上更新. https://github.com/hackstoic/golang-open- ...

随机推荐

  1. js中调用mangeto的js翻译

    第一步: <script type="text/javascript"> Translator.add('英文','<?php echo this->__( ...

  2. 设计模式之二十四:訪问者模式(Visitor)

    訪问者模式: 定义了一个作用于一个类的一些操作,訪问者模式同意在不改变类的前提下添加一些操作. Represent an operation to be performed on the elemen ...

  3. linux下创建用户并且限定用户主目录

    Linux 系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统.用户的账号 一方面可以帮助系统管理员对使用系统的用户进 ...

  4. 使用ionic与cordova(phonegap)进行轻量级app开发前的环境配置与打包安卓apk过程记录

     前言 有人说:"如果你恨一个人,就让ta去接触cordova(phonegap)",这是因为这里面的水很深,坑很多,真让人不是一般地发狂.或许有幸运的人儿基本顺顺利利就配置完环境 ...

  5. 20160115--Hibernate

    package com.hanqi.dao; import static org.junit.Assert.*; import java.util.*; import org.hibernate.se ...

  6. Maximum & Minimum Depth of Binary Tree

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  7. MySQL之外键约束

    MySQL之外键约束 MySQL有两种常用的引擎类型:MyISAM和InnoDB.目前只有InnoDB引擎类型支持外键约束.InnoDB中外键约束定义的语法如下: [CONSTRAINT [symbo ...

  8. Jexus 配置多个站点

    一:jexus配置站点的文件在 siteconf文件夹中,里面有多少个配置文件,就可以配置多少个站点 如我的里面有3个配置文件,其中default是原始文件,site1和siteconf就是我网站的配 ...

  9. std::string转化大小写(C++)

    #include <string> #include <algorithm> void test() { std::string strA="QQQQWWWqqqqq ...

  10. Android加载图片小结

    应用中用到图片加载需要解决的问题 无网络环境下图片不可用 图片的本地缓存,或者默认预加载的图片 低配置机型,加载图像资源超内存(OutOfMemory, OoM) 需要合理使用内存,尤其是bitmap ...