其中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. sqlite3 not found问题解决方法

    测试发现,有些Android手机自带sqlite3命令,有些不带.对于不带sqlite3的手机,我们可以手动将sqlite3加入系统. 执行如下命令 adb remount adb push 路径/s ...

  2. Azure File

    Azure File 服务使用标准 SMB 2.1 协议提供文件共享.Azure 中运行的应用程序现在可以使用熟悉的标准文件系统 API(如 ReadFile 和 WriteFile)在虚拟机之间轻松 ...

  3. 为什么Java中字符串是不可变的

    前言 在Java中,字符串是一个不可变的类,一个不可变的类指的是它的实例对象不能被修改,所有关于这个对象的信息在这个对象被创建时已初始化且不能被改变. 不可变类有很多优势,这篇文章总结了字符串类之所以 ...

  4. eclipse配置文件导出问题

    关于eclipse配置文件导出问题 eclipse的默认配置一般不能满足我们的要求,我们一般会修改一些配置,如字体.背景颜色.快捷键及一些template等等,这样方便我们的开发.可是当我们新建一个工 ...

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

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

  6. Java Se:Java Security

    Java API中有很多都使用了SecurityManager,这到底是什么玩意?最近看公司的产品的源码,也有不少SecurityManager.AccessControlContext等相关的代码, ...

  7. Linux 引导修复

    前些天,我的Ubuntu老提示"Filesystem root"空间不足,于是,我煞笔的用win pe去扩展空间,结果,空间扩展不成,反倒丢失了引导..... 于是就上网查资料,看 ...

  8. android RelativeLayout 动态设置高度

    定义: private RelativeLayout mrlay; 调高度: mrlay = (RelativeLayout) findViewById(R.id.rlay_1); android.v ...

  9. Java Eclipse解决中文字体太小

       解决方式有两种: 一.把字体设置为Courier New   操作步骤:打开Elcipse,点击菜单栏上的“Windows”——点击“Preferences”——点击“Genneral”——点击 ...

  10. ab 性能测试工具的使用(Web并发测试)

    1.下载 http://pan.baidu.com/s/1hrlAbI0 2.命令介绍 参数的介绍 n在测试会话中所执行的请求个数.默认时,仅执行一个请求. -c一次产生的请求个数.默认是一次一个. ...