网上之所以有这么多版本的KMP算法,是因为有的人写的是最大长度串版本的,有的人写的是next数组版本的(具体区别看下面博文),有的人写的是next优化版的,有的人写的是未优化的,不同人写的循环方法不同,这些写法间的效率是有一定区别的

KMP算法具体讲解看这篇博客,讲的非常非常详细:

https://blog.csdn.net/v_july_v/article/details/7041827#

重点应该在理解Next数组和Next数组的优化

我试着再写一下我理解的优化过程:

比如这张图:

设上面的串为A[],下面的串为B[],下标从0开始

根据最大长度串数组C的定义:

当前子串字符之前的字符串中,有多大长度的相同前缀后缀。例如如果C [j] = k,代表j 之前的字符串中有最大长度为k 的相同前缀后缀。

对于abab这个子串来说,最大长度串数组C就是0 0 1 2,那么next数组(未优化版)就是最大长度值整体向右移动一位,然后初始值赋为-1,即-1 0 0 1。

我们会发现当发生A[3]c与B[3]b失配后,左移两位(3-next[3])后,会A[3]c会再次与B[1]b失配,事实上这是必然发生的,

回看next数组的定义(其实也就是最大长度串数组):j 之前的字符串中有最大长度为k 的相同前缀后缀。既然后缀的这个字符已经失配了,那么前缀相同地方的字符也一定会失配,所以要避免这个情况发生,也就是若:B[j] = B[ next[j] ]就要让B[j] = B[ next[j] ]。

总结一下这个过程:

先求出最大长度串数组,整体左移一位,若B[j] = B[ next[j] ]即B[j] = B[ next[j] ]

最后给出一个nenxt优化版本的代码

 int a[];
int b[];
int len1, len2;
int Next[];
void getNext()
{
int k = -, j = ;
Next[] = -;
while(j < len2)
{
if(k == - || b[j] == b[k])
{
k++;
j++;
if(b[j] != b[k])
Next[j] = k;
else//如果这一步失败 那么同值的也会失败
Next[j] = Next[k];
}
else
k = Next[k];
}
}
int kmp()
{
getNext();
int i = , j = ;
while(i < len1)
{
if(j == - || a[i] == b[j])
{
i++;
j++;
}
else
j = Next[j];
if(j == len2)
return i+-len2;
//返回的是匹配到的index,如果是求次数或对错的话需要修改
}
return -;
}

KMP算法不同写法之间区别的更多相关文章

  1. Python 细聊从暴力(BF)字符串匹配算法到 KMP 算法之间的精妙变化

    1. 字符串匹配算法 所谓字符串匹配算法,简单地说就是在一个目标字符串中查找是否存在另一个模式字符串.如在字符串 "ABCDEFG" 中查找是否存在 "EF" ...

  2. KMP算法的一次理解

    1. 引言 在一个大的字符串中对一个小的子串进行定位称为字符串的模式匹配,这应该算是字符串中最重要的一个操作之一了.KMP本身不复杂,但网上绝大部分的文章把它讲混乱了.下面,咱们从暴力匹配算法讲起,随 ...

  3. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  4. KMP算法深入解析

    本文主要介绍KMP算法原理.KMP算法是一种高效的字符串匹配算法,通过对源串进行一次遍历即可完成对字符串的匹配. 1.基础知识的铺垫 字符串T的前k(0 =< k <=tlen)个连续的字 ...

  5. 字符串匹配KMP算法详解

    1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有比较详细的通俗易懂的讲解,另一方面也怪自己没有沉下心来研究.最近在leetcode上又遇见字符串匹配的题目,以此 ...

  6. KMP算法详细分解

    1. 引言 给定一个主串(以 S 代替)和模式串(以 P 代替),要求找出 P 在 S 中出现的位置,此即串的模式匹配问题. Knuth-Morris-Pratt 算法(简称 KMP)是解决这一问题的 ...

  7. 算法 kmp算法

    kmp算法是改进后的字符匹配算法,它与bf算法的区别是,每次从串与主串匹配失败后,从串与主串匹配的位置不同. 下面具体说下这两种算法的区别: 主串:BABCDABABCDABCED 从串:ABCDAB ...

  8. KMP算法的next函数求解和分析过程

    转自 wang0606120221:http://blog.csdn.net/wang0606120221/article/details/7402688 假设KMP算法中的模式串为P,主串为S,那么 ...

  9. 从头到尾测地理解KMP算法【转】

    本文转载自:http://blog.csdn.net/v_july_v/article/details/7041827 1. 引言 本KMP原文最初写于2年多前的2011年12月,因当时初次接触KMP ...

随机推荐

  1. Oracle 闪回归档(Flashback Data Archive)

    --检查权限 SELECT * FROM dba_sys_privs WHERE privilege LIKE '%FLASH%'; --设置权限 GRANT dba TO testuser;--设置 ...

  2. final,finally和finalize三者的区别和联系

    对于初学者而言(当然也包括我)对于这三者真的不是很陌生,经常会看到它们.但对于三者之间的区别和联系一直是懵懵懂~~ 今天心情不错,那就简单总结一下它们几个的区别和联系吧.如果又不对的地方欢迎批评指正~ ...

  3. Python 下载图片的几种方法

    import osos.makedirs('./image/', exist_ok=True)IMAGE_URL = "http://image.nationalgeographic.com ...

  4. js生成邀请码(2)

    //生成邀请码方法一 /*function createInviteCode() { var s = [],a=6,b=10; var chars = "123456789QWERTYUIP ...

  5. leetcode443

    使用两个数组分别记录字符和对应的数字,然后清除原来的vector,重新向里面添加元素.注意判断1个字符时,不将'1'加入vector. int compress(vector<char>& ...

  6. nginx配置域名

    其他都一样,就特别说下server块的配置. server { listen 80; server_name www.icweshop.com; # 注意:这里你填写的域名必须在/etc/hosts中 ...

  7. iter创建一个可以被迭代的对象

    #!/usr/bin/env python obj = iter([11,22,33,44]) #iter 创建一个可以被迭代的对象 print(obj) r1 = next(obj) print(r ...

  8. C语言获取系统时间

    localtime函数 #include <stdio.h> #include <time.h> int main () { time_t t; struct tm *lt; ...

  9. ListView里面adapter的不同分类的item

    public class PlayAdapter extends BaseAdapter { /** * 标题的item */ public static final int ITEM_TITLE = ...

  10. 关于contentprovider的几个问题

    说说ContentProvider与Android数据存储的关系? contentprovider是程序之间共享数据的唯一方式,android中没有公共数据区域的说法,每个进程启动都是不同的用户,与P ...