首先是简单的朴素匹配算法

    /*
* 返回子串t在主串s的位置,若不存在则返回0
*/
public static int index(String s, String t) { int i = 0;//i记录主串当前位置的下标
int j = 0; //j记录子串当前位置的下标 char[] c = t.toCharArray();
char[] d = s.toCharArray();
while(i < s.length() && j < t.length()) {
if(c[i] == d[j]) {
i++;
j++;
if(j == t.length()) {
break;
}
}else {
i = i - j;//如果不匹配i退回到上次匹配首位的下一位
j = 0;
}
}
if(j == t.length()) {
return i - j + 1;
}
return 0;
}

举例说明:

s是 abcabcabd t是 abcabd,朴素的匹配算法每次发现不对都要重新回到上次匹配的首位,也就是要重新在s从找一次t的和第一个字符匹配的字符。

但是像这个例子t字符串中一开始就有ab后面也有ab,也就是说如果匹配到最后一位发现不匹配的时候,就可以直接进行到这里

所以这就是kmp改进的地方,先自行处理一下t字符串,找到t字符串中与前缀有重复的。建立一个next数组记录下这个重复,就比如这个t匹配到最后一个时发现s[5]和t[5]匹配失败,但是t[3]t[4]和t[1]t[2]是重复的,所以这里可以直接进行s[5]和t[3]的匹配。从代码的角度讲就是当i=5,j=5时,s[i]和t[j]匹配失败,那就修改j跳过之前与t字符串前缀重复的。

这是一个next数组,这里j=0时没有前缀所以在匹配的时候就应该重t[0]开始匹配,j=1时前缀是a但是t[1]是b所以没有重复,所以还是0,一直到j=3,a和前缀a重复所以所以在匹配的时候就应该重t[1]开始匹配,到j=4,ab和前缀ab重复所以所以在匹配的时候就应该重t[2]开始匹配,j=5的时候abd和前缀abc并没有重复所以应该重t[0]开始匹配。

再然后就是这个next数组怎么计算。。

声明一个k初始化为0用于记录前缀被重复的长度了,就比如t[3]和t[0]重复就记1,此时next[]相应的位置就是1(k),t[3]t[4]和t[0]t[1]重复就记2,此时此时next[]相应的位置就是2(k),t[3]t[4]t[5]t[0]t[1]t[3不]重复就置0。

整体代码:

public static int KmpIndex(String s, String t) {
int i = 0;
int j = 0; //j记录子串当前位置的下标
int[] next = new int[t.length()];
char[] c = t.toCharArray();
char[] d = s.toCharArray();
int k = 0; while(j < t.length()) {
if(k == 0 && j == 0) {
//第一个字符的前后缀为空
next[j++] = 0;
}else {
//使用k来记住已经和前者匹配到那个位置了
if(k == 0 ) {
//k=0 就是上一个未匹配
if(c[k] != c[j]) {
//不相等就是不匹配
next[j++] = 0;
}else {
//相等就是匹配,next[j]等于k+1,然后增加k和j的值
next[j++] = ++k;
}
}else {
//k!=0 就是上k个都已经匹配了
if(c[k] != c[j]) {
//不相等就是不匹配而且之后要重头匹配 k=0
next[j++] = 0;
k = 0;
}else {
//相等就是匹配,next[j]等于k+1,然后增加k和j的值
next[j++] = ++k;
}
}
}
}
j = 0;
while(i < s.length() && j < t.length()) {
if(d[i] == c[j]) {
i++;
j++;
if(j == t.length()) {
break;
}
}else {
j = next[j];
}
}
if(j == t.length()) {
return i - j;
}
return 0;
}

kpm字符串匹配算法的更多相关文章

  1. 字符串匹配算法 - KMP

    前几日在微博上看到一则微博是说面试的时候让面试者写一个很简单的字符串匹配都写不出来,于是我就自己去试了一把.结果写出来的是一个最简单粗暴的算法.这里重新学习了一下几个经典的字符串匹配算法,写篇文章以巩 ...

  2. Boyer-Moore 字符串匹配算法

    字符串匹配问题的形式定义: 文本(Text)是一个长度为 n 的数组 T[1..n]: 模式(Pattern)是一个长度为 m 且 m≤n 的数组 P[1..m]: T 和 P 中的元素都属于有限的字 ...

  3. KMP单模快速字符串匹配算法

    KMP算法是由Knuth,Morris,Pratt共同提出的算法,专门用来解决模式串的匹配,无论目标序列和模式串是什么样子的,都可以在线性时间内完成,而且也不会发生退化,是一个非常优秀的算法,时间复杂 ...

  4. 字符串匹配算法之BF(Brute-Force)算法

    BF(Brute-Force)算法 蛮力搜索,比较简单的一种字符串匹配算法,在处理简单的数据时候就可以用这种算法,完全匹配,就是速度慢啊. 基本思想 从目标串s 的第一个字符起和模式串t的第一个字符进 ...

  5. 【原创】通俗易懂的讲解KMP算法(字符串匹配算法)及代码实现

    一.本文简介 本文的目的是简单明了的讲解KMP算法的思想及实现过程. 网上的文章的确有些杂乱,有的过浅,有的太深,希望本文对初学者是非常友好的. 其实KMP算法有一些改良版,这些是在理解KMP核心思想 ...

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

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

  7. 4种字符串匹配算法:KMP(下)

    回顾:4种字符串匹配算法:BS朴素 Rabin-karp(上) 4种字符串匹配算法:有限自动机(中) 1.图解 KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R ...

  8. 4种字符串匹配算法:BS朴素 Rabin-karp(上)

    字符串的匹配的算法一直都是比较基础的算法,我们本科数据结构就学过了严蔚敏的KMP算法.KMP算法应该是最高效的一种算法,但是确实稍微有点难理解.所以打算,开这个博客,一步步的介绍4种匹配的算法.也是& ...

  9. 字符串匹配算法之Sunday算法

    字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...

随机推荐

  1. CSS属性过滤

    在前端领域,当我们想在ie6及以下版本和标准浏览器的样式不同我们怎么做呢 此时此刻不得不提到过滤器:即一种对特定浏览器显示和隐藏规则的声明方法 1.下划线属性过滤器 符合标准的浏览器都会忽略这个声明, ...

  2. mysql 免安装版本 与问题记录

    将文件解压到D盘, 创建 my.ini 配置文件, ------------------复制进去--------------------- [client] port=3306 default-cha ...

  3. Java第二次作业——数组和String类

    Java第二次作业--数组和String类 学习总结 1.学习使用Eclipse关联jdk源代码,查看String类的equals()方法,截图,并学习其实现方法.举例说明equals方法和==的区别 ...

  4. CDQZ集训DAY10 日记

    又一次跪了,跪在了神奇的数据范围上. T1上来打完暴力之后觉得是数据结构题,像三维偏序,于是开始往各种数据结构上想,主席树,线段树+calc,平衡树,树套树,CDQ……最终在经过一番思考之后选择去打C ...

  5. Centos7 安装jdk,MySQL

    报名立减200元.暑假直降6888. 邀请链接:http://www.jnshu.com/login/1/20535344 邀请码:20535344 学习阿里云平台的云服务器配置Java开发环境.我现 ...

  6. WinForm控件之【CheckBox】

    基本介绍 复选框顾名思义常用作选择用途,常见的便是多选项的使用: 常设置属性.事件 Checked:指示组件是否处于选中状态,true为选中处于勾选状态,false为未选中空白显示: Enabled: ...

  7. 通过代数,数字,欧几里得平面和分形讨论JavaScript中的函数式编程

    本文是对函数式编程范式的系列文章从而拉开了与以下延续一个. 介绍 在JavaScript中,函数只是对象.因此,可以构造函数,作为参数传递,从函数返回或分配给变量.因此,JavaScript具有一流的 ...

  8. 程序员到sql笔记

    1最近准备面试,总结一下之前学过到东西.

  9. 人民网基于FISCO BCOS区块链技术推出“人民版权”平台

    FISCO BCOS是完全开源的联盟区块链底层技术平台,由金融区块链合作联盟(深圳)(简称金链盟)成立开源工作组通力打造.开源工作组成员包括博彦科技.华为.深证通.神州数码.四方精创.腾讯.微众银行. ...

  10. C# 不同访问符的访问级别

    public----成员可以由任何代码访问. private----成员只能由类中的代码访问(如果没有使用任何关键字,就默认使用这个关键字). internal----成员只能由定义它的项目(程序集) ...