KMP算法next数组求解
关于KMP算法,许多教材用的是递推式求解,虽然代码简洁,但是有些不好理解,这里我介绍一种迭代求next数组的方法
KMP算法关键部分就是滑动模式串,我们可以每次滑动一个单位,直到出现可能匹配的情况,此时失配处next数组的值,就是失配处当前对应的元素下标
如下图,在X处失配,则向右滑动1个单位,可见这种情况是明显不可能匹配的,于是再滑,一直滑到可能出现匹配情况为止,“C”与“?”可能是匹配的,故应停止在此处,故失配处next数组的值就是“C”所在下标
基于上述思路的代码如下:
#include<stdio.h>
#include<string.h> void GetNext(char *str, int *arr); void main()
{
char str[] = "abaabacaba";
int next[]; GetNext(str, next);
//结果:-1 0 0 1 1 2 3 0 1 2
} void GetNext(char *str, int *arr)
{
int i, j, k, flag, len = strlen(str); //整体思路
//从失配处每次向右滑动一个单位,一直滑到可能匹配上的位置则停止
//即滑动串与失配处之前的串的相应部分再次一一匹配
for (i = , arr[] = -; i < len; i++)
{
//i表示next数组下标,即失配处序号
for (j = ; j <= i; j++)
{
//j表示模式串向右滑动次数
for (k = , flag = ; k < i - j; k++)
{
//k表示滑动后模式串的子串
if (str[k] != str[k + j])
{
flag = ;
break;
}
}
if (flag == || j == i)
{
arr[i] = i - j;
break;
}
}
}
}
这个方法虽然没有递推式那么高效,但是整体还是比较好理解的,而且模式串一般不会太长,这种方法也不会花费太多时间就能得出next数组。
另外用php实现完整的kmp算法,这次用已知的next[x](x < i)求未知的next[i],并且next[i]定义为从0~i都是匹配的,即在i+1处才失配:
<?php function getNext(string $pattern)
{
$next = [];
if (empty($pattern)) {
return $next;
} else {
$next[0] = -1;
for ($i = 1; $i < strlen($pattern) - 1; $i++) {
$k = $next[$i - 1];
if ($k == -1) {
$next[$i] = $pattern[$k + 1] == $pattern[$i] ? 0 : -1;
} else {
while ($k > -1) {
if ($pattern[$k + 1] == $pattern[$i]) {
$next[$i] = $k + 1;
break;
}
$k = $next[$k];
}
$next[$i] = -1;
}
}
}
return $next;
} function kmp(string $pattern, string $string)
{
$next = getNext($pattern);
if (empty($next)) {
return false;
}
for ($i = 0, $j = -1; $i < strlen($string);) {
if ($j + 1 == strlen($pattern)) {
return $i - $j - 1;
}
if ($string[$i] == $pattern[$j + 1]) {
$i++;
$j++;
} else {
if ($j != -1) {
$j = $next[$j];
} else {
$i++;
}
}
}
return false;
}
KMP算法next数组求解的更多相关文章
- 转载-KMP算法前缀数组优雅实现
转自:http://www.cnblogs.com/10jschen/archive/2012/08/21/2648451.html 我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见 ...
- KMP算法 Next数组详解
题面 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果你不知道这是什么意思也不要问,去百 ...
- KMP算法-next函数求解
KMP函数求解:一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为KMP算法.KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串 ...
- 数据结构之KMP算法next数组
我们要找到一个短字符串(模式串)在另一个长字符串(原始串)中的起始位置,也就是模式匹配,最关键的是找到next数组.最简单的算法就是用双层循环来解决,但是这种算法效率低,kmp算法是针对模式串自身的特 ...
- KMP算法&next数组总结
http://www.cnblogs.com/yjiyjige/p/3263858.html KMP算法应该是每一本<数据结构>书都会讲的,算是知名度最高的算法之一了,但很可惜,我大二那年 ...
- 第4章学习小结_串(BF&KMP算法)、数组(三元组)
这一章学习之后,我想对串这个部分写一下我的总结体会. 串也有顺序和链式两种存储结构,但大多采用顺序存储结构比较方便.字符串定义可以用字符数组比如:char c[10];也可以用C++中定义一个字符串s ...
- 【文文殿下】浅谈KMP算法next数组与循环节的关系
KMP算法 KMP算法是一种字符串匹配算法,他可以在O(n+m)的时间内求出一个模式串在另一个模式串下出现的次数. KMP算法是利用next数组进行自匹配,然后来进行匹配的. Next数组 Next数 ...
- poj1961(kmp算法next数组应用)
题目链接:https://vjudge.net/problem/POJ-1961 题意:给定一个长为n的字符串(n<=1e6),对于下标i(2<=i<=n),如果子串s(1...i) ...
- POJ-2752(KMP算法+前缀数组的应用)
Seek the Name, Seek the Fame POJ-2752 本题使用的算法还是KMP 最主要的片段就是前缀数组pi的理解,这里要求解的纸盒pi[n-1]有关,但是还是需要使用一个循环来 ...
随机推荐
- 给VMware下的Linux扩容磁盘空间到根分区(以centos7.0为例)
一.扩展VMWare硬盘空间 关闭Vmware 的 Linux系统,这样,才能在VMWare菜单中设置: VM -> Settings... -> Hardware -> Hard ...
- Jmeter(七)Jmeter脚本优化(数据与脚本分离)
午休时间再来记一记,嗯..回顾着使用Jmeter的历程,想着日常都会用到的一些功能.一些组件:敲定了本篇的主题----------是的.脚本优化. 说起脚本优化,为什么要优化?又怎么优化?是个永恒的话 ...
- Python首次安装后运行报错(0xc000007b)的解决方法
最近在安装完Python后运行发现居然报错了,错误代码是0xc000007b,于是通过往上查找发现是因为首次安装Python缺乏VC++库的原因,下面通过这篇文章看看如何解决这个问题吧. 错误提示 ...
- Android知识点textview加横线的属性
textView.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG ); //下划线 textView.getPaint().setAntiAlias(tr ...
- go语言功能代码
一.数据类型转换 package main import ( "fmt" "strconv" ) func main() { //int到string str ...
- jms和activemq简介
一.JMS简介 JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消 ...
- 更优雅的使用Git
JavaScript之禅已经发过两篇 Git 相关的文章了.一篇文章,教你学会Git :浅显易懂,如果你还不会 Git 可以先去看看.Git的奇技淫巧 :介绍了一些实用的操作.今天为大家带来第三篇,如 ...
- Java - 35 Java 实例
Java 实例 本章节我们将为大家介绍 Java 常用的实例,通过实例学习我们可以更快的掌握 Java 的应用. Java 环境设置实例 Java 实例 – 如何编译一个Java 文件? Java 实 ...
- Android手动控制软键盘的开启和关闭,判断软键盘是否显示;
工具类,拿走就能用: import android.annotation.TargetApi; import android.app.Activity; import android.content. ...
- .NET C#获取当前网页地址
摘自:https://www.cnblogs.com/vichin/p/6004249.html 设当前页完整地址是:http://www.jb51.net/aaa/bbb.aspx?id=5& ...