关于KMP的next函数的原理分析
KMP是上学期学数据结构时候学的,当时就没学太明白,后来又自己琢磨了几次,但始终是一知半解。今天起床了又想起来KMP,以下是思考得到的一点东西。
首先学过kmp的都知道要写两个函数,一个计算next数组,一个kmp主体函数,那么next数组里存的到底是啥呢。首先答案是:next[i]存的是字符串[0,i]的前后缀最长公共长度减1的值。下面先解释下前后缀。
引用张别人的图:
也就是说只有一个元素时候前后缀都为空,即不能拿整个字符串作为前缀or后缀,注意这点即可。
我们把第i位对应的最大公共前后缀长度减1的值作为next[i]的值,这一点是为了之后计算的方便,后续会提到。
下面是next数组的计算函数
//创建NEXT数组
int create_next(int* address,int len,string str)
{
address[0]=-1;
for(int i=1;i<len;i++)
{
int k=address[i-1];
while(str[k+1]!=str[i]&&k>-1)
{
k=address[k];
}
if(str[k+1]==str[i])
{
++k;
}
address[i]=k;
}
}
首先address[0]=-1,原因上面说了。每次for循环里的i是代表字符串的游标,每次for循环干的事是计算出字符串[0,i]的最长公共前后缀元素个数,当然我们可以一个个数,先看str[0]=str[i]成立不成立,再看str[0]=str[i-1]&&str[1]=str[i]成立不成立,依次类推。但是这样重复考察了太多元素,故我们采用简便一点的方法,我画了个图。
如图,前后黑括号代表[0,i-1]的最长公共前后缀,但str[k+1]!=str[i],那么我们要找黑括号里的更小的蓝括号,让前后蓝括号相同。注意看图,找到满足上面条件蓝括号的时候,左边蓝括号就在左边黑括号的左端,右边蓝括号在右边黑括号的右端,这不就是求[0,k]或者[i-1-k,i-1]的最长公共前后缀长度么?再看下k=next[k],是不是这回懂为啥这么写了。从最开始的黑括号寻找蓝括号的部分就是next函数第一部分,也就是下面这个while循环做的事情,想一想是不是
int k=address[i-1];
while(str[k+1]!=str[i]&&k>-1)
{
k=address[k];
}
找到上面的一对蓝括号之后,就出去while循环了,接下来是:
if(str[k+1]==str[i])
{
++k;
}
address[i]=k;
这段意思是:此时k是蓝括号的长度-1,那么k+1就是蓝括号往右第一个元素,如果这个元素等于str[i],那么公共长度就加1,否则直接返回k。如果从while出来时候k等于-1,那表示找不到这样的蓝括号,那么只能考察str[0]和str[i]了,如果相等公共长度就为1,否则就为0。再看下函数开始,如果address[i-1]就等于-1的话,while循环直接就出来了,出来直接判断str[-1+1]==str[i]成立不成立,所以这里可以看出我们当时为什么要把长度-1作为next数组值。以上,不对的地方请指出,不懂的可以评论交流。
闲着没事又敲了个python的:
def create_next(next_list,str):
str_len=len(str)
next_list.clear()
next_list.append(-1)
k=-1
for i in range(str_len):
while k!=-1 and str[k+1]!=str[i]:
k=next_list[k]
if str[k+1]==str[i]: #若k为-1也成立
k+=1
next_list.append(k)
next_list=[]
def KMP(target,pattern):
#TARGET目标串,pattern模式串
create_next(next_list,pattern)
tar_len=len(target)
pat_len=len(pattern)
k=-1
for i in range(tar_len):
while k!=-1 and target[i]!=pattern[k+1]:
k=next_list[k]
if target[i]==pattern[k+1]:
k+=1
if k==pat_len-1: #模式串全部匹配,即匹配成功
return i-pat_len+1
x="bacbababadababacmbabacaddababacasdsd"
y="ababaca"
print(KMP(x,y))
关于KMP的next函数的原理分析的更多相关文章
- 【转载】Select函数实现原理分析
Select函数实现原理分析 <原文> select需要驱动程序的支持,驱动程序实现fops内的poll函数.select通过每个设备文件对应的poll函数提供的信息判断当前是否有资源可用 ...
- PHP 基础系列(三) 【转】PHP 函数实现原理及性能分析
作者:HDK (百度) 前言 在任何语言中,函数都是最基本的组成单元.对于PHP的函数,它具有哪些特点?函数调用是怎么实现的?php函数的性能如何,有什么使用建议?本文将从原理出发进行分析结合实际的性 ...
- Android中Input型输入设备驱动原理分析(一)
转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...
- 使用AsyncTask异步更新UI界面及原理分析
概述: AsyncTask是在Android SDK 1.5之后推出的一个方便编写后台线程与UI线程交互的辅助类.AsyncTask的内部实现是一个线程池,所有提交的异步任务都会在这个线程池中的工作线 ...
- (转)Android 系统 root 破解原理分析
现在Android系统的root破解基本上成为大家的必备技能!网上也有很多中一键破解的软件,使root破解越来越容易.但是你思考过root破解的 原理吗?root破解的本质是什么呢?难道是利用了Lin ...
- SPI协议及工作原理分析
说明.文章摘自:SPI协议及其工作原理分析 http://blog.csdn.net/skyflying2012/article/details/11710801 一.概述. SPI, Serial ...
- C语言可变参数函数实现原理
一.可变参数函数实现原理 C函数调用的栈结构: 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈. 本 ...
- web压测工具http_load原理分析
一.前言 http_load是一款测试web服务器性能的开源工具,从下面的网址可以下载到最新版本的http_load: http://www.acme.com/software/http_load/ ...
- memcache分布式部署的原理分析
下面本文章来给各位同学介绍memcache分布式部署的原理分析,希望此文章对你理解memcache分布式部署会有所帮助哦. 今天在封装memcache操作类库过程中,意识到一直以来对memcach ...
随机推荐
- Wannafly Winter Camp 2020 Day 6H 异或询问 - 二分
给定一个长 \(n\) 的序列 \(a_1,\dots,a_n\),定义 \(f(x)\) 为有多少个 \(a_i \leq x\) 有 \(q\) 次询问,每次给定 \(l,r,x\),求 \(\s ...
- 使用pip安装Python库超时解决办法
如果在国内安装Python库,强烈推荐使用豆瓣的源http://pypi.douban.com/simple/ 可以这样使用 pip install -i http://pypi.douban.com ...
- LAMP环境搭建与配置(3)
PHP配置 查看PHP配置文件的位置 # /usr/local/php/bin/php -i |grep -i "loaded configuration file" ...
- 与soul上的一个妹子聊天有感
写此篇的原因: 妹子说,我考上公务员了~,当时自己自己顿时哽咽了,不知道说什么,习惯性的说了句,恭喜恭喜啊.感受到妹子的欢喜与喜悦,我也没必要打扰她的兴致,她开心就好了嘛. 每个人的成就都是自己奋斗的 ...
- php弱语言特性-计算科学计数法
php处理字符串时存在一个缺陷问题,如果字符串为“1e1”,本该是一个正常的字符串,但是php会将它认为是科学计数法里面的e: 也就是按照数学的科学计数法来说:1e1=10^1=10,因此php会把这 ...
- Ioc依赖注入:Unity4.0.1 在项目中的应用 (MVC和API)
使用Unity的好处网上有很多,百度一下即可 这里引用了一篇关于面向接口编程的好处的文章作为引申:https://blog.csdn.net/Cyy19970527/article/details/8 ...
- Codeforces Round #616 (Div. 2) C. Mind Control
题目链接:http://codeforces.com/contest/1291/problem/C 思路: 我们可以很容易想到,只有前m-1个人才能影响m的选择的大小,后面的人无法影响. 如果所有人都 ...
- babel plugin
a = () => {}, // Support for the experimental syntax 'classProperties' isn't currently enabled ya ...
- ASP.NET MVC5 的请求管道和运行生命周期
https://www.jianshu.com/p/848fda7f79e0 请求处理管道 请求管道是一些用于处理HTTP请求的模块组合,在ASP.NET中,请求管道有两个核心组件:IHttpModu ...
- POJ2528Mayor's posters 线段树,离散化技巧
题意:一个坐标轴从1~1e7,每次覆盖一个区间(li,ri),问最后可见区间有多少个(没有被其他区间挡住的) 线段树,按倒序考虑,贴上的地方记为1,每次看(li,ri)这个区间是否全是1,全是1就说明 ...