其中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算法的更多相关文章

  1. 算法数据结构 | 只要30行代码,实现快速匹配字符串的KMP算法

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法数据结构专题的第29篇文章,我们来聊一个新的字符串匹配算法--KMP. KMP这个名字不是视频播放器,更不是看毛片,它其实是由Kn ...

  2. 字符串匹配算法——KMP算法学习

    KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...

  3. 数据结构4.3_字符串模式匹配——KMP算法详解

    next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...

  4. [Algorithm] 字符串匹配算法——KMP算法

    1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...

  5. 字符串匹配算法——KMP算法

    处理字符串的过程中,难免会遇到字符匹配的问题.常用的字符匹配方法 1. 朴素模式匹配算法(Brute-Force算法) 求子串位置的定位函数Index( S, T, pos). 模式匹配:子串的定位操 ...

  6. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  7. 字符串查找KMP算法(转)

    如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...

  8. 字符串查找KMP算法

    如果你用过ctrl+F这个快捷键,那么你有很大的概率使用过这个算法,这就是在待查找字符串(可能有成千上万个字符)中找出模式串(比较小,可能有几个字符),可能找到大于或者等于1次的位置.例如,在abab ...

  9. c算法:字符串查找-KMP算法

    /* *用KMP算法实现字符串匹配搜索方法 *该程序实现的功能是搜索本目录下的所有文件的内容是否与给定的 *字符串匹配,如果匹配,则输出文件名:包含该字符串的行 *待搜索的目标串搜索指针移动位数 = ...

随机推荐

  1. db2简单语句记录

    db2start db2 connect reset 断开连接 db2 drop db xxx 删除数据库 db2 list tables 查看表 db2 create database xxx 建立 ...

  2. 资源list:Github上关于大数据的开源项目、论文等合集

    Awesome Big Data A curated list of awesome big data frameworks, resources and other awesomeness. Ins ...

  3. 更换mysql数据目录后出现ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2) 的解决办法

    服务器上的mysql默认数据目录为/var/lib/mysql/,同时服务器的/空间不是很大,而近期又有大量的日志需要导入进行分析,时常搞得/的空间捉襟见肘,晚上一狠心就想把mysql的数据目录转移到 ...

  4. Tomcat:bio nio 的设计

    BIO  由Acceptor接收Socket,将其转交给Worker来处理. NIO 由Acceptor接收Socket,将其转交给Poller来轮询处理.Poller再将可处理的Socket交给Wo ...

  5. spring annotation简述

    一.Annotation基本概念 Annotation是jdk5以后出现的新特性,在jdk中,其内置了许多自己的Annotation,例如@Override,@SuppresWarning,@Depr ...

  6. spring 依赖注入(IOC DI)

    依赖注入(IOC DI) 依赖注入的两种方式: 1. set注入 Spring要求使用set注入方式的时候,Bean需要提供一个无参数的构造方法.并提供一个属性的setter方法.例如: packag ...

  7. Sql Server 2008R2 遇到了BCP导入各种中文乱码的问题

    今天玩BCP导入数据的时候,有文件格式,有中文字符串问题……以下是历程,和大家分享一下,希望不要走我的弯路 主要那个表是一个翻译表,一个文件里面内涵几十种语言,所以很容易发现问题. 0.使用最常用的语 ...

  8. SQL SERVER同步环境新增发布对象时不能生成(sp_MS+表名)同步存储过程

    在配置了同步的用户环境(订阅端:请求订阅) 在发布端: 1.企业管理器SSMS—复制—本地发布—发布属性—项目(选中发布对象) 2.在企业管理里—查看快照代理状态(启动) 在订阅服务器: USE [D ...

  9. shell脚本变量

    既然是变量,自然分变量名和变量值,在使用的时候一定要注意哪些地方需要用变量名,哪些地方需要用变量的值. 自定义变量 shell变量不需要声明,随用随定义,给变量赋值的时候要注意 shell是空格敏感的 ...

  10. wc

    $wc [-lwc] filename统计的文件的信息,缺省参数会按照lwc的顺序输出全部三种信息 -l统计文件的行数 -w统计文件的字数,字以空格和换行符分隔 -c统计文件的字符数,包括换行等 例子 ...