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

    /*
* 返回子串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. django基础知识之视图:

    视图 视图接受Web请求并且返回Web响应 视图就是一个python函数,被定义在views.py中 响应可以是一张网页的HTML内容,一个重定向,一个404错误等等 响应处理过程如下图:

  2. LinkedList源码分析:JDK源码分析系列

    如果本文中有不正确的地方请指出由于没有留言可以在公众号添加我的好友共同讨论. 1.介绍 LinkedList 是线程不安全的,允许元素为null的双向链表. 2.继承结构 我们来看一下LinkedLi ...

  3. 把大象装进冰箱:HTTP传输大文件的方法

    上次我们谈到了HTTP报文里的div,知道了HTTP可以传输很多种类的数据,不仅是文本,也能传输图片,音频和视频.   早期互联网上传输的基本上都是只有几k大小的文本和小图片,现在的情况则大有不同.网 ...

  4. NOIP2015斗地主题解 7.30考试

    问题 B: NOIP2015 斗地主 时间限制: 3 Sec  内存限制: 1024 MB 题目描述 牛牛最近迷上了一种叫斗地主的扑克游戏.斗地主是一种使用黑桃.红心.梅花.方片的A到K加上大小王的共 ...

  5. bzoj1052 9.20考试 第二题 覆盖问题

    1052: [HAOI2007]覆盖问题 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2004  Solved: 937[Submit][Statu ...

  6. STM32F4xx系列_独立看门狗配置

    看门狗由内部LSI驱动,LSI是一个内部RC时钟,并不是准确的32kHz,然而看门狗对时间的要求不精确,因此可以接收: 关键字寄存器IWDG_KR: 写入0xCCCCH开启独立看门狗,此时计数器开始从 ...

  7. 【分治】黑白棋子的移动-C++

    题目描述 有2n个棋子(n≥4)排成一行,开始为位置白子全部在左边,黑子全部在右边,如下图为n=5的情况: ○○○○○●●●●● 移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也 ...

  8. 如何使用百度EasyDL进行情感分析

    使用百度EasyDL定制化训练和服务平台有一段时间了,越来越能体会到EasyDL的易用性.在此之前我也接触过不少的深度学习平台,如类脑平台.Google的GCP深度学习平台.AWS深度学习平台,但我觉 ...

  9. 分布式Streaming Data Processing - Samza

    ​ 现在的主流的互联网应用越来越依赖streaming data来提供用户一些interesting statistics insights.以linkedin为例,最近90天有多少人看过你的link ...

  10. C# 针对特定的条件进行锁操作,不用lock,而是mutex

    背景:用户领取优惠券,同一个用户需要加锁验证是否已经领取,不同用户则可以同时领取. 上代码示例: 1.创建Person类 /// <summary> /// Person类 /// < ...