文章目录

  • 1. KMP由来
  • 2. KMP算法基本原理
  • 3. 代码
  • 4. Leetcode 28. 实现 strStr()

1. KMP由来

  • 上一节说的BM算法是最高效、最常用的字符串匹配算法。
  • 最知名的却是KMP,它3位作者(D.E.Knuth,J.H.Morris,V.R.Pratt),算法的全称是Knuth Morris Pratt 算法,简称KMP算法。

2. KMP算法基本原理

类似于BM里的概念:坏字符(不能匹配的),好前缀(已经匹配的那段)


  • KMP算法目的:当遇到坏字符后,对于已经对比过的好前缀,将模式串多滑动几位

    借一张图理解一下:


    上面可以看出,可以事先预处理好模式串,与主串比较时,直接用next数组

  • 构建next数组(失效函数)
    next 数组含义:当前字符之前的字符串(不含当前)中,最大长度的相同前缀后缀子串。如果next [j] = k,代表 j 之前的字符串中有最大长度为 k 的相同前缀后缀子串。

  • 失效函数计算方法
    方法1:暴力求解子串长度,效率低

    方法2:
    case1

    case2

    如果 b[k] != b[j] , 则我要在前面部分里寻找能和包含 b[j] 的后缀匹配的最长前缀子串;
    b[k] 前面的最长匹配前缀长度就是 next[k],那么其后面一个字符就是 b[ next[k] ],如果它等于b[j],那么next[j+1] = next[k] + 1
    参考文献

3. 代码

王争的代码不好理解,找了书和别的人的代码参考

/*** @description: KMP字符串匹配算法* @author: michael ming* @date: 2019/6/22 17:15* @modified by: */
#include <string>
#include <iostream>
using namespace std;
void calNexts(char *b, int m, int *next)
{next[0] = -1;int j = 0, k = -1;while(j < m){if(k == -1 || b[j] == b[k]){j++;k++;next[j] = k;}elsek = next[k];}
//    for(j = 0; j < m; ++j)//调试代码
//        cout << "next[" << j << "] " << next[j] << endl;
}
int str_kmp(char *a, int n, char *b, int m)
{int *next = new int [m];calNexts(b, m, next);int i = 0, j = 0;while(i < n && j < m){if(j == -1 || a[i] == b[j]){i++;j++;}else{j = next[j];}}if(j == m){delete [] next;return i-j;}delete [] next;return -1;
}
int main()
{string a = "abcacabcbcbaccba", b = "cbaccba";cout << a << "中第一次出现" << b << "的位置(从0开始)是:" << str_kmp(&a[0],a.size(),&b[0],b.size());return 0;
}

时间复杂度O(n+m),空间复杂度O(m)

4. Leetcode 28. 实现 strStr()

  • 使用 kmp 匹配
class Solution {public:int strStr(string s, string p) {return kmp(s, p);}int kmp(string& s, string& p){int n1 = s.size(), n2 = p.size();vector<int> next(n2+1);calnext(p, next);int i = 0, j = 0;while(i < n1 && j < n2){if(j == -1 || s[i] == p[j]){i++,j++;}elsej = next[j];}if(j == n2)return i-j;return -1;}void calnext(string& p, vector<int>& next){int i = 0, j = -1;next[0] = -1;while(i < p.size()){if(j == -1 || p[i] == p[j]){i++,j++;next[i] = j;}elsej = next[j];}}
};

0 ms 6.9 MB C++

字符串匹配算法(KMP)相关推荐

  1. 【GO语言实现字符串匹配算法-KMP算法】

    [GO语言实现字符串匹配算法-KMP算法] KMP算法原理说明: KMP算法是一种改进的字符串匹配算法,是有D.E.Knuth,J.H.Morris和V.R.Pratt提出的,所以被称为KMP算法. ...

  2. 字符串匹配算法KMP算法

    数据结构中讲到关于字符串匹配算法时,提到朴素匹配算法,和KMP匹配算法. 朴素匹配算法就是简单的一个一个匹配字符,如果遇到不匹配字符那么就在源字符串中迭代下一个位置一个一个的匹配,这样计算起来会有很多 ...

  3. js实现kmp算法_字符串匹配算法KMP算法

    数据结构中讲到关于字符串匹配算法时,提到朴素匹配算法,和KMP匹配算法. 朴素匹配算法就是简单的一个一个匹配字符,如果遇到不匹配字符那么就在源字符串中迭代下一个位置一个一个的匹配,这样计算起来会有很多 ...

  4. 字符串匹配算法——KMP算法学习

    KMP算法是用来解决字符串的匹配问题的,即在字符串S中寻找字符串P.形式定义:假设存在长度为n的字符数组S[0...n-1],长度为m的字符数组P[0...m-1],是否存在i,使得SiSi+1... ...

  5. [Algorithm] 字符串匹配算法——KMP算法

    1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...

  6. 浅析字符串匹配算法——KMP算法(附CF 535D-Tavas and Malekas)

    引入 在计算机中,人类的语言.文字等往往利用字符串进行保存,而字符串的匹配也对人们的生活产生着举足轻重的作用,例如个人信息的匹配.搜索引擎的使用等,为了在庞大的数据中找到我们所需的数据,字符串匹配的效 ...

  7. 字符串匹配算法 KMP

    #include<stdio.h> //串的定长顺序存储表示 #define MAXSTRLEN 50 // // 用户可在50以内定义最大串长 #define MAXLEN 255 ty ...

  8. 字符串匹配算法 -- BM(Boyer-Moore) 和 KMP(Knuth-Morris-Pratt)详细设计及实现

    文章目录 1. 算法背景 2. BM(Boyer-Moore)算法 2.1 坏字符规则(bad character rule) 2.2 好后缀规则(good suffix shift) 2.3 复杂度 ...

  9. BF,KMP,BM三种字符串匹配算法性能比较

    三种最基本的字符串匹配算法是BF,KMP以及BM,BF算法是最简单直接的匹配算法,就是逐个比较,一旦匹配不上,就往后移动一位,继续比较,所以比较次数很都. 关于KMP和BM的详细介绍可以参考下面的两个 ...

  10. 字符串匹配算法(三):KMP(KnuthMorrisPratt)算法

    文章目录 KMP 原理 next数组的构建 代码实现 KMP 一提到字符串匹配算法,想必大家脑海中想到的第一个必然就是KMP算法,KMP算法的全称叫做KnuthMorrisPratt算法,与上一篇博客 ...

最新文章

  1. 利用ISCSI存储技术构建IP存储网络(安全篇)
  2. 好像是第一次在公司外的论坛上公开演讲
  3. BZOJ 2427 软件安装(强连通分量+树形背包)
  4. JWT【JSON Web Token】 简述
  5. C++基础11-类和对象之操作符重载1
  6. 关于分布式事务的几个问题
  7. 2054无法登陆mysql_张虹亮'blog » ubuntu20.04安装mysql8之后,php5程序和phpmyadmin出现#2054 无法登录MySQL服务器的解决方案...
  8. 「1024 程序员节」各大公司和程序员们都是怎么过的?你都做了哪些计划或安排?
  9. java调用mac终端命令_JAVA之前 - mac终端命令行
  10. 为了帮朋友抢jk,写了一个抢拍器,支持淘宝天猫京东。使用教程如下:
  11. websockets 和 socketio 的比较
  12. 输入输出工具技术(ITTO)要背吗?——软考高项笔记8
  13. 区块链入门教程 。阮一峰
  14. 3dmax:3dmax三维VR渲染设置之高级灯光渲染(经典案例—矩形光源打造灯箱效果)图文教程
  15. su如何变成实体_Sketchup实体工具怎么使用? SU实体工具的使用方法
  16. Android正确使用Scheme协议打开App,兼容浏览器scheme的二次跳转
  17. PHP检查日期格式是否符合
  18. css3中-moz、-ms、-webkit意思
  19. 一种设计软件界面的万能HTML标签
  20. 记录一次504超时的解决方案

热门文章

  1. vs2010创建和使用动态链接库(dll)
  2. 交通警察手势信号(动画演示)
  3. 基于PHP实现一个简单的在线聊天功能(轮询ajax )
  4. bzoj2435: [Noi2011]道路修建 树上dp
  5. JDK源码包结构分类
  6. Jquery 常用总结
  7. 行向量,列向量,行主序矩阵,列主序矩阵
  8. 【dll 返回字符串 】2
  9. raft协议中统计一条log被多少节点复制
  10. I2C和SPI注定要打一架