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- ...
随机推荐
- 不错的JS
http://www.17sucai.com/preview/47509/2013-10-18/Sequence-master/photo-stack/index.html
- 看到当年自己学SQL Server 的笔记
数据库 数据量DataBase,不同类型的数据应该放到不同的数据库中, .便于对各个数据类别进行个性管理 .避免命名冲突 .安全性更高; table(表):数据库中的关系指的就是表; 一张表就是一个类 ...
- linux循环递归设置权限
这里给出一个循环递归得到对文件夹和文件分别有效的设置方法: find /path -type f -exec chmod 644 {} \; #对目录和子目录里的文件 find /path -type ...
- BZOJ 1087 互不侵犯king
Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. Input 只有一行,包 ...
- [多线程同步练习]PV操作
看一个较为复杂的生产者-消费者问题: 问题描述 桌子上有一只盘子,每次只能向其中放入一个水果.爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果.只有盘子为空时 ...
- 转 git操作小结
UNDER MIT LICENSE. 公司几乎所有的项目都是使用 git 仓库来管理代码,以前对 git 只有些肤浅的了解,每次提交代码或者上线的时候总是会提心吊胆,生怕出现一些未知的问题.经过三个月 ...
- XOR双向链表
这是一个数据结构.利用计算机的的位异或操作(⊕),来降低双向链表的存储需求. ... A B C D E ... –> next –> next –> next –> < ...
- image.xx.com 通过haproxy 跳转到内部图片服务器
<pre name="code" class="html">http://www.hyyche.com/#main C:\Users\Adminis ...
- Google Play Services Library update and missing symbol @integer/google_play_services_version
转自http://stackoverflow.com/questions/19843784/google-play-services-library-update-and-missing-symbol ...
- [Leetcode][Python]20: Valid Parentheses
# -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 20: Valid Parentheseshttps://oj.leetcod ...