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

    /*
* 返回子串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. kindeditor在线文本编辑器过滤HTML的方法

    在使用kindeditor文本编辑器时遇到的问题,客户直接从Excel里粘贴文本内容到文本编辑器中(能不能再懒一些),然后不调整粘贴内容直接就保存(你敢不敢再懒一些)!对于这种很无语的行径,我只能对他 ...

  2. Drools规则引擎-判断集合(List)是否包含集合

    问题场景 在使用Drools规则引擎时,有朋友会遇到这样的问题,就是在when部分判断的两个参数都是集合类型,比如两个List,此时要判断一个集合是否包含另外一个集合的内容. 拿一个具体的例子来说明, ...

  3. k8s学习 - 概念 - ReplicationController

    k8s学习 - 概念 - ReplicationController 我们有了 pod,那么就需要对 pod 进行控制,就是同一个服务的 podv我需要启动几个?如果需要扩容了,怎么办?这里就有个控制 ...

  4. SSRS报表-级联筛选参数刷新后不能默认全选 -问题解决方案

    好久没有写博客了,最近更新完善修复了SSRS报表的一些问题,和大家分享. 问题描述: 报表中,区域->专区->省份->地级市 此四个筛选参数是联动的,在DataSet中前一父级参数作 ...

  5. 「PowerBI相关」一款极其优秀的DAX建模工具Tabular Editor

    做Excel插件开发的时间久了,大部分人的印象是笔者是做软件开发,谈不上软件,也是插件开发级别. 但笔者更希望大家记住的身份是做BI开发,特别是企业级的BI. 故也借着Excel催化剂这个平台,输送一 ...

  6. 个人永久性免费-Excel催化剂功能第50波-批量打印、导出PDF、双面打印功能

    在倡导无纸化办公的今天,是否打印是一个碍眼的功能呢,某些时候的确是,但对于数据的留存,在现在鼓吹区块链技术的今天,仍然不失它的核心价值,数据报表.单据打印出来留存,仍然是一种不可或缺的数据存档和防篡改 ...

  7. 个人永久性免费-Excel催化剂功能第20波-Excel与Sqlserver零门槛交互-数据上传篇

    Excel作为众多数据存储的交换介质,在不同的系统内的数据很少可以很连贯地进行整合分析,一般的业务系统都会提供导出Excel作为标配功能供用户使用系统内生成的数据. 此时最大的问题是,Excel很维去 ...

  8. [POJ 2888]Magic Bracelet[Polya Burnside 置换 矩阵]

    也许更好的阅读体验 \(\mathcal{Description}\) 大意:给一条长度为\(n\)的项链,有\(m\)种颜色,另有\(k\)条限制,每条限制为不允许\(x,y\)颜色连在一起.要求有 ...

  9. Js中关于内部方法、实例方法、原型方法、静态方法的个人见解。

    function foo(name){ this.name=name; // 实例方法 this.GetName=function(){ console.log("my name is &q ...

  10. python正则表达式与re模块-02

    正则表达式 正则表达式与python的关系 # 正则表达式不是Python独有的,它是一门独立的技术,所有的编程语言都可以使用正则 # 但要在python中使用正则表达式,就必须依赖于python内置 ...