Knuth-Morris-Pratt Algorithm
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的更多相关文章
- 我所理解的 KMP(Knuth–Morris–Pratt) 算法
假设要在 haystack 中匹配 needle . 要理解 KMP 先需要理解两个概念 proper prefix 和 proper suffix,由于找到没有合适的翻译,暂时分别称真实前缀 和 真 ...
- 字符串匹配算法--KMP字符串搜索(Knuth–Morris–Pratt string-searching)C语言实现与讲解
一.前言 在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个词W的出现位置.此算法通过运用对这个词在不匹配时本身就包含足够的信息 ...
- 笔试算法题(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 ...
- Aho - Corasick string matching algorithm
Aho - Corasick string matching algorithm 俗称:多模式匹配算法,它是对 Knuth - Morris - pratt algorithm (单模式匹配算法) 形 ...
- GO语言的开源库
Indexes and search engines These sites provide indexes and search engines for Go packages: godoc.org ...
- Go语言(golang)开源项目大全
转http://www.open-open.com/lib/view/open1396063913278.html内容目录Astronomy构建工具缓存云计算命令行选项解析器命令行工具压缩配置文件解析 ...
- 一个字符串搜索的Aho-Corasick算法
Aho和Corasick对KMP算法(Knuth–Morris–Pratt algorithm)进行了改进,Aho-Corasick算法(Aho-Corasick algorithm)利用构建树,总时 ...
- [转]Go语言(golang)开源项目大全
内容目录 Astronomy 构建工具 缓存 云计算 命令行选项解析器 命令行工具 压缩 配置文件解析器 控制台用户界面 加密 数据处理 数据结构 数据库和存储 开发工具 分布式/网格计算 文档 编辑 ...
- go语言项目汇总
Horst Rutter edited this page 7 days ago · 529 revisions Indexes and search engines These sites prov ...
- Golang优秀开源项目汇总, 10大流行Go语言开源项目, golang 开源项目全集(golang/go/wiki/Projects), GitHub上优秀的Go开源项目
Golang优秀开源项目汇总(持续更新...)我把这个汇总放在github上了, 后面更新也会在github上更新. https://github.com/hackstoic/golang-open- ...
随机推荐
- The Unique MST (判断是否存在多个最小生成树)
The Unique MST Time Limit: 10 ...
- 一封在JSP课程结束之后给学生的信
<JSP应用程序设计>这门课终于考完了,虽然题目有点难,但我看大部分同学考的还可以,算上平时成绩应该都能拿到一个满意的分数. 再次感谢大家一个学期来对我的支持,跟大家一起的这个学期很开心, ...
- FieldInfo.IsSpecialName Property【转】
Gets a value indicating whether the corresponding SpecialName attribute is set in the FieldAttribute ...
- 获取一个请求的URL内容
using System.Net; 1. // 创建一个请求的URL. WebRequest request = WebRequest.Create("http://www ...
- 说说VS 2015 RC最新开发工具的体验
有两个我感觉是提高效率的地方: 1.智能提示的改进,鼠标只要移动到代码上面的类型.字段,就会显示相应的提示,这大大提高我们开发时候需要按F12才能看到定义的内容.下面上图,给大家形象化: 2.管理Nu ...
- User cannot be resolved to a type
出现 User cannot be resolved to a type 不知道具体问题出在哪里但是我经过将全路径输入并保存后错误消失 将User选上,然后点击保存就可以了! 最后我发现错误消失了!
- doGet与doPost的区别
转自:http://blog.csdn.net/luoweifu/article/details/7865243 目录(?)[-] 不同点一 不同点二 输入表单inputhtml Serlvlet ...
- Android Spinner 下拉列表
private Spinner spinner ; private List<String> list ; private ArrayAdapter< ...
- hadoop笔记之Hive的管理(远程登录方式)
Hive的管理(三) Hive的管理(三) Hive的远程服务 远程服务启动方式 端口号10000 启动方式:hive --service hiveserver (注意:以JDBC或ODBC的程序登录 ...
- querySelectorAll的BUG
querySelector和querySelectorAll是W3C提供的新的查询接口 目前 IE8/9及Firefox/Chrome/Safari/Opera 的最新版已经支持它们. 但是Eleme ...