对于字符串的匹配问题,即在字符串原串中找到子串第一次出现在原串的下标,第一个方案是遍历字符串原串,在每次原串字符偏移时,遍历子串,如果子串可以遍历完成则代表已经找到了子串第一次在原串中出现的位置,返回此时原串遍历指针的下标。

int strSearch(const char *src, const char *sub) {int srclen = strlen(src);int sublen = strlen(sub);int i;int j;for(i = 0; srclen - i >= sublen; i++) {for (j = 0; src[i + j] == sub[j]; ++j) {}if (sub[j] == 0) {return i;}}return NOT_FOUND;
}

虽然这个方法可以很容易找到与子串匹配的原串下标,但是它的时间复杂度太高了,对原串进行遍历需要 n-m 次循环,n为原串中字符个数,m为遍历子串字符个数。而遍历子串需要m次循环,所以整个算法的时间复杂度为O(m*(n-m)),近似与O(n^2)。时间复杂度较高,于是抛弃这种算法,选择KMP算法来实现串匹配。

KMP算法中最核心的部分之一便是next函数,关于next函数,它是为了在遍历字符串子串时可以选择性跳过一些重复判断的字符,极大的减小了算法的时间复杂度。形成一个next数组,数组中存放跳过的数字。

例: a a b a a b a a
        0 0 1 0 1 2 3 4

由于字符的特点,前两个字符必定为0,在遍历子串时需要从第三个字符进行遍历

a a b a a b a a
0 0 1                如果在第三位失配时,前面仅有a一个相同。则next[2] = 1;

a a b a a b a a
0 0 1 0              如果在第四位失配时,前面没有相同的。则next[3] = 0;

a a b a a b a a
0 0 1 0 1 2 3   如果在第七位失配时,前面有aab 相同,则next[5] = 3;

第一次比较时比较的第一个字符,如果相同则第二次只用比较第二个字符,即比较时用子串中比较未相同或没有进行比较过的sub[ j ] 与 失配前一个字符即sub[i - 1];

sub[ j ] == sub[i -1]!

推导:

第一次:i = 2a a b a a b a a     第三位失配,则比较i = 1的字符与j = 0的字符 ,0 0                 相同 : j++;  next[2] = 1;   i++;  j = 0第二次:i = 3a a b a a b a a  第四位失配,则比较i = 2的字符与j = 1的字符,0 0 1                不相同:则需要与上一次所比较的字符来比较 即b 与第一个 a 比较;j = 1             即比较i = 2的字符与j = 0的字符;不相同:且 j = 0;无法再比较,next[3] = 0; i++; 第三次:i = 4a a b a a b a a   第五位失配,则比较i = 3的字符与j = 0的字符,0 0 1 0          相同 : j++;  next[4] = 1;   i++;j = 0
第四次:i = 5a a b a a b a      第六位失配,则比较i = 2的字符与j = 1的字符,0 0 1 0 1            相同 : j++;  next[5] = 2;   i++;j = 2             第五次:i = 6a a b a a b a     第七位失配,则比较i = 2的字符与j = 1的字符,0 0 1 0 1 2      相同 : j++;  next[6] = 3;   i++;j = 3             

由上述推导过程可以得到以下代码实现:

while (sub[i]) {if (sub[i-1] == sub[j]) {next[i++] = ++j;} else if (j != 0) {j = next[j];} else {next[i++] = j;}
}

至此,next函数实现就已经完成了。

KMP算法-next函数介绍相关推荐

  1. KMP 算法并非字符串查找的优化 [转]

    算法书和数据结构书对 KMP算法多有介绍,称只需对字符串扫描一遍不需回溯云云 .然而 ,它恐怕只应该作为一种思想存在 ;用于实际的字符串查找并不理想 .要费劲心血实现和优化它 ,才能在特定的字符串上略 ...

  2. 模式搜索的KMP算法详解与C语言代码实现

    Table of Contents 模式搜索的KMP算法 如何更好地理解和掌握 KMP 算法? 推荐文章 Knuth-Morris-Pratt 字符串查找算法,简称为 "KMP算法" ...

  3. KMP算法的核心,是一个被称为部分匹配表(Partial Match Table)的数组以及next数组求解

    KMP算法的核心,是一个被称为部分匹配表(Partial Match Table)的数组.我觉得理解KMP的最大障碍就是很多人在看了很多关于KMP的文章之后,仍然搞不懂PMT中的值代表了什么意思.这里 ...

  4. c语言kmp算法代码,C语言KMP算法的实现

    KMP算法在模式与主串之间存在许多"部分匹配"的情况下,比BF算法快.(注意,接下来的串都是以下标为1作为起始储存位置.) 下面说一下实现代码: 首先是预定义和类型定义: #def ...

  5. 史上比较难懂的KMP算法介绍

    书生来自秦朝南海郡,是一秃头学子. 取经之路漫漫,沉心学习方见始终. 目录 前言 一.串匹配简介及KMP引入 1.串匹配 2.暴力法串匹配 3.KMP算法相关引入 二.KMP核心思想 三.KMP算法 ...

  6. c语言数据结构kmp中next计算,数据结构——关于KMP算法中next函数的详细解析

    以前看到数据结构中字符串的模式匹配时,花了半天的时间,才把KMP算法中的next函数整明白了,结果过了几天在看到这时,只记得next[j+1]=next[j]+1,但是有时候能套公式正确算出,有时候就 ...

  7. KMP算法、AC自动机算法的原理介绍以及Python实现

    KMP算法 要弄懂AC自动机算法,首先弄清楚KMP算法. 这篇文章讲的很好: http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E ...

  8. 算法-发明KMP算法的唐纳德·克努特是怎么想到失配函数next[j]的?

    背景 字符串模式匹配,普通模式非常好理解,拿着模式串依次与主串做比较,知道完全匹配,但是这种算法,主串得不断地回溯,时间复杂度O(n*m). 唐纳德·克努特 有没有降低时间复杂度的可能,唐纳德·克努特 ...

  9. 【数据结构和算法笔记】KMP算法介绍

    BF暴力算法: 当模式串位i与目标串i比较时两字符不相等,则i的移动方式:i=i-j+1 j的移动方式:j=0   KMP算法简介: ●KMP模式匹配中,当模式串位j与目标串位i比较两字符不相等 i  ...

最新文章

  1. poj 3537 Crosses and Crosses 博弈论之grundy值
  2. RNN-循环神经网络-02Tensorflow中的实现
  3. 数据库流行度5月排行榜:Oracle企稳PostgreSQL飙升
  4. toast, 警告窗
  5. oceanbase mysql模式安装了obproxy之后的连接方法
  6. Linux上的查找命令之locate查找
  7. 关闭centos6.7不必要的服务
  8. 小白学电脑计算机的组成,新手学电脑步骤,从零开始学电脑
  9. nrf52840 内部 flash 结构
  10. CefSharp中文帮助文档
  11. 一套数据中心弱电系统安全运维服务方案,完整版素材!
  12. ASP入门教程 1小时ASP入门,非常简单
  13. SFDC 基本知识网络图
  14. 2020美容师(初级)模拟考试及美容师(初级)复审模拟考试
  15. Word中插入PDF
  16. Ubuntu 1804 切换国内源
  17. MIND——Modality independent neighbourhood descriptor 模态无关邻域描述符
  18. DroneKit(四)——无人机协同
  19. 【电脑讲解】电脑D盘不见了怎么恢复
  20. WJMZBMR打osu! / Easy【期望dp】

热门文章

  1. 基于Arria10的H.264 4K高性能编解码器模块视频演示
  2. 攻防世界:crypt(RC4)
  3. Vue前端页面跳转,登录成功跳转页面
  4. 【第4期-智能驾驶汽车系列术语概念解析】第3节:基于三点参数方程的曲率计算方法
  5. 我在CSDN发表原创文章,被别人拿去发了一篇北大核心,论文难道就是东拼西凑?
  6. 融合黄金正弦和曲线自适应的多策略麻雀搜索算法
  7. GAL汉化界的一点实话。。。。。
  8. 2017杭电ACM集训队单人排位赛 - 2 -1002 地狱飞龙 (辛普森公式求积分)(模板)
  9. Android Q (十四)ANGLE
  10. 什么是LIDAR(激光雷达),如何标注激光点云数据?