匹配字符串的KMP算法
其中next序列,表示子串的前后缀最大匹配长度. 例如对于字符串C[], next[i]表示子串c[0 .. i]中, 前缀与后缀的最大匹配长度.
举例如果子串是 abcuab, 其前缀是a, ab, abc, abcu, abcua, 后缀是 b, ab, uab, cuab, bcuab, 其中匹配的最大子串是ab, 长度是2.
按定义挨个计算next的值
public static int[] getNexts(char[] tt)
{
int[] nexts = new int[tt.length];
nexts[0] = 0;
// 从1到结束, 挨个计算next
for (int i = 1; i < tt.length; i++)
{
// 在给定的子串里, 记录matched时, 最大的长度值
for (int j = 0; j < i; j++)
{
boolean matched = true;
// 使用 k, 依次比较从 0 到 j 和从 i-j 到 i的字符是否相等, 注意下标都是从小往大移动
for (int k = 0; k <= j; k++)
{
if (tt[k] != tt[i-j+k])
{
matched = false;
break;
}
} // 匹配的, 记录最大长度
if (matched)
{
int length = j + 1;
if (nexts[i] < length)
nexts[i] = length;
}
}
} return nexts;
}
改进后的方法, 在遍历中依次记录next的值, 令循环减少许多
/**
* 只使用两个起始下标, 来计算和记录next序列
*
* @param tt
* @return
*/
public static int[] getNexts2(char[] tt)
{
int[] nexts = new int[tt.length]; nexts[0] = 0;
// 前缀起始下标
int prefix = 0;
// 后缀起始下标
int suffix = prefix + 1;
// 匹配长度
int len = 0;
while(suffix < tt.length)
{
if (tt[prefix] == tt[suffix])
{
// 如果匹配, 则记录下当前的next最大值, 并且将前缀和后缀下标都往大移动一位
prefix++;
len++;
if (nexts[suffix] < len)
nexts[suffix] = len;
}
else
{
// 如果不匹配, 则当前长度归零, 并且前缀回归起点, 而后缀依然往后走
len = 0;
prefix = 0;
}
suffix++;
} return nexts;
}
字符串搜索过程:
public static int kmpFind(char[] ss, char[] tt)
{
// 内容串下标
int spos = 0;
// 搜索串下标
int tpos = 0; // 计算next序列
int[] nexts = getNexts2(tt);
while (spos < ss.length)
{
if (ss[spos] == tt[tpos])
{
// 匹配上后, 判断是否满足退出条件
if (tpos == tt.length - 1) return spos - tt.length + 1;
if (tpos == ss.length - 1) return -1;
// 否则继续往后匹配
spos++;
tpos++;
}
else
{
// 未匹配的情况下, 如果搜索串是第一步都未中, 则内容串下标继续移动
if (tpos == 0)
spos++;
// 否则调整搜索串下标到前一步的next值(忽略掉最大前缀)
else
tpos = nexts[tpos - 1];
}
} return -1;
}
http://jakeboxer.com/blog/2009/12/13/the-knuth-morris-pratt-algorithm-in-my-own-words/
匹配字符串的KMP算法的更多相关文章
- 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...
- 字符串匹配算法——KMP算法学习
KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...
- 数据结构4.3_字符串模式匹配——KMP算法详解
next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...
- [Algorithm] 字符串匹配算法——KMP算法
1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...
- 字符串匹配算法——KMP算法
处理字符串的过程中,难免会遇到字符匹配的问题.常用的字符匹配方法 1. 朴素模式匹配算法(Brute-Force算法) 求子串位置的定位函数Index( S, T, pos). 模式匹配:子串的定位操 ...
- 字符串模式匹配KMP算法
一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...
- 字符串查找KMP算法(转)
如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...
- 字符串查找KMP算法
如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...
- c算法:字符串查找-KMP算法
/* *用KMP算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...
随机推荐
- Mac系统如何编辑hosts文件
Mac系统如何编辑hosts文件 Hosts 是一个没有扩展名的系统文件,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”,当用户在浏览器中输入一个需要登录的网址时,系 统会首先 ...
- Java中并发问题整理
1. java中有几种方法可以实现一个线程? 使用Runnable,Callable,Thread或者线程池 2. 如何停止一个正在运行的线程? 可以使用正在运行的线程,支持线程中断,通常是定义一个v ...
- uniqid函数产生唯一id,减少碰撞几率
$uuid = str_replace(".","",uniqid(mt_rand(100000,999999),true)); //基于当前时间微妙数,与mt ...
- sshd安装
centos yum install openssh-server #chkconfig --level 2345 sshd on #service sshd restart 重新启动 #netsta ...
- 如何退出调起多个Activity的Application?
1.记录打开的Activity 每打开一个activity,即记录下来,需要关闭时,关闭每一个activity即可. 2.发送特定的广播 在需要结束应用时,发送一个特定广播,每个activity收到此 ...
- 测试驱动开发(Test-Driven Development,简称TDD)--单元测试-->提高代码质量
!!! 1.估算和做项目计划时要算上单元测试时间 2.开发之前写单元测试代码 盖房子的时候,工人师傅砌墙,会先用桩子拉上线,以使砖能够垒的笔直,因为垒砖的时候都是以这根线为基准的.TDD就像这样,先写 ...
- MapReduce二次排序
默认情况下,Map 输出的结果会对 Key 进行默认的排序,但是有时候需要对 Key 排序的同时再对 Value 进行排序,这时候就要用到二次排序了.下面让我们来介绍一下什么是二次排序. 二次排序原理 ...
- 让你脱离google不能访问的烦恼
大陆封了google已有20多天了,给开发者带来了许多不便.只需两步让你的google可以使用: 1.设置hosts: 访问:https://git.oschina.net/kawaiiushio/m ...
- 编写一个Java应用程序,该应用程序包括2个类:Print类和主类E。Print 类里有一个方法output()功能是输出100 ~ 999之间的所有水仙花数(各位数字的 立方和等于这个三位数本身,如: 371 = 33 + 73 + 13。)在主类E的main方法中来 测试类Print
package zuoye; public class print { void output() { System.out.println("100-999之间的水仙花数是:") ...
- 元组tuple
tuple和list的主要区别就是tuple里的元素的是不能改变的,即tuple时immutable的 #创建tuple >>> tupa = (12 , 'ed' , 34) &g ...