其中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. Git 分支管理策略

    分支管理策略 下面我们来说一下一般企业中开发一个项目的分支策略: 主分支 master 开发分支 develop 功能分支 feature 预发布分支  release bug 分支 fixbug 其 ...

  2. iOS启动过程

    1.main函数 | 2.UIApplicationMain      * 创建UIApplication对象      * 创建UIApplication的delegate对象 | 3.delega ...

  3. 调用meitu秀秀.so文件实现美图功能

    本文属于实战系列,是对<Android C代码回调java方法>等文的实践,调用meitu秀秀的libmtimage-jni.so文件来实现图片的美化功能 首先反编译得到/libmtima ...

  4. run() 和 start() 的区别

    1) start: 用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面(指主线程下面)的代码.通过调用Thread类的start()方法来启动一个 ...

  5. iOS---UISearchBar限制输入字数

    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText // called when text ...

  6. Extjs插入图片

    Extjs并没有提供直接的组件来显示图片.网上通过设置textfield的InputType为Image然后再修改dom对象来实现,其实 image的属性值并没有包含在Extjs的官方文档当中.可以通 ...

  7. PlateSpin 完全复制由于LVM没有可用空闲空间导致失败

    使用PlateSpin复制居然会由于LVM的卷组VG没有空闲可用的空间(available free space in the LVM volume group)创建快照而导致失败,特此记录一下:免得 ...

  8. Sql Server之旅——第十站 看看DML操作对索引的影响

    我们都知道建索引是需要谨慎的,当只有利大于弊的时候才适合建,我们也知道建索引是需要维护成本的,这个维护也就在于DML操作了, 下面我们具体看看到底DML对索引都有哪些内幕.... 一:delete操作 ...

  9. Oracle表字段的增加、删除、修改和重命名

    本文主要是关于Oracle数据库表中字段的增加.删除.修改和重命名的操作. 增加字段语法:alter table tablename add (column datatype [default val ...

  10. C++/CLI——读书笔记《Visual C++/CLI从入门到精通》 第Ⅱ部分

    =================================版权声明================================= 版权声明:本文为博主原创文章 未经许可不得转载  请通过右 ...