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

    /*
* 返回子串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. echo-nginx-module的安装、配置、使用

    一.下载压缩包 [root@www nginx-1.16.0]# wget https://github.com/openresty/echo-nginx-module/archive/v0.61.t ...

  2. 使用nexus搭建npm私服

    第一步,下载nexus 下载链接: https://pan.baidu.com/s/1GOYi2M3nT4Wcy7JEYmnqdA 提取码: a9hf 第二步,解压缩 我下载的是nexus-3.16. ...

  3. .Net Core 创建和使用中间件

    1. 定义中间内容 1.1 必须有一个RequestDelegate 委托用了进入一个中间件 1.2 通过构造函数设置这个RequestDelegate委托 1.3 必须有一个方法Task Invok ...

  4. Mysql CPU使用率长期100%的解决思路备忘

    最近一台服务器的CPU使用率长期保持在100%的状态,查看进程发现是Mysql服务导致的.于是搜索各方资料,终于成功解决问题.备忘以及分享一下,希望可以帮助各位新手朋友. (服务器运行环境是Windo ...

  5. Bzoj 3124: [Sdoi2013]直径 题解

    3124: [Sdoi2013]直径 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1222  Solved: 580[Submit][Status] ...

  6. C#类型详解

    一.类型成员 类成员定义有(public.private.internal.protected). Public--对任何类和成员都是公开的,无限制 Private--是私有的,仅能由类内部代码访问, ...

  7. 微信小程序开发--API界面交互

    一.wx:showActionSheet(上拉菜单) 属性 类型 默认值 必填 说明 itemList Array.<string>   是 按钮的文字数组,数组长度最大为 6 itemC ...

  8. 程序员到sql笔记

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

  9. NOIP2018普及T1暨洛谷P5015 标题统计 题解

    题目链接:https://www.luogu.org/problemnew/show/P5015 分析: 这道题大概是给个签到分吧.很显然的字符串操作.本篇题解主要帮助初学者,请大佬略过. 首先给大家 ...

  10. Git更改提交

    提交记录我们的工作历史记录,提交自身是一成不变的.Git提供了几个工具和命令,抓门用来帮助修改完善版本库中的提交. 实际工作中存在很多情况需要我们去修改或返工某个提交或者整个提交序列: 1,可以在某个 ...