KMP算法

刚开始学字符串算法的时候其实是十分抵触的,暴力匹配效率也不低嘛,但是在做题的时候才发现数据量真的很大,暴力还是炸了
所以还是乖乖的学字符串算法吧

先说几个字符串算法中的常用概念吧
文本串 :已有的长长的字符串(一般我写成T)
模式串 :要被查询的内容,就是说在文本串中要查找模式串(一般我写成P)(文本 串就是长的,模式串就是短的,要在文本串里找模式串,中华文化博大精深,不好描述,有二义性。。。)

然后看KMP算法吧:
KMP算法中文翻译是:字符串查找算法
顾名思义,就是一个 文本串 T 内查找一个 模式串 P 的出现位置。

当然,暴力算法就可以做但是效率太低,原因是一次匹配失败就要重新从模式串的头开始。。。效率低下,而KMP算法通过对这个词在不匹配时本身包含的信息来确定下一个匹配将在哪里开始的发现,从而避免重新检查先前匹配的字符,提高程序运行效率
为了提高效率,KMP算法会在匹配之前预处理一个fail数组(有的地方写的是next数组,其实是一样的)借助 failfail 数组,可以在匹配过程中减少很多冗余的匹配操作,由此提高了算法的效率。KMP 算法的时间复杂度为O(n+m)

首先看看fail数组
对于字符串 s=s0​s1​…sn−1​,如果 j 是满足 s0…j​=si−j…i​ 的最大值,则 faili​=j,其中 sa…b​ 表示字符串 s 从下标 a 到下标 b 的子串。对于不存在 s0…j​=si−j…i​ 的情况,fail[i]​=−1。

例如,对于字符串aababaab,则 fail 值如下表所示:

S       A   A   B   A   B   A   A   B
fail    −1  0  −1   0   −1  0   1   2

手算一下就知道了
我们先不管fail是这么算出来的,(当然和手算的算法不一样)
我们先学会怎么用,假设fail已经就出来了,我们开始匹配了
先给出伪代码

KMP(T, P)fail = getFail(P)match = -1for i = 0 to T.length - 1while match >= 0 and P[match + 1] != T[i]match = fail[match]if P[match + 1] == T[i]match += 1if match == P.length - 1return truereturn false

我们用两个值match和i来标记模式串 P 和匹配串 T 分别匹配到的下标位置,初始状态i=0,match=-1

会用之后给出fail数组的计算方法的伪代码,实际上和上面的伪代码一样可以理解为自己匹配自己

getFail(P)m = P.lengthfail[0] = -1match = -1for i = 1 to P.length - 1while match >= 0 and P[match + 1] != P[i]match = fail[match]if P[match + 1] == P[i]match += 1fail[i] = matchreturn fail

好了,下面给出KMP算法的模板,一个是fail的一个是next的,个人习惯与第一个

fail数组的

void getFail(char *P, int *fail) {int match = -1;fail[0] = -1;for (int i = 1; P[i]; ++i) {while (match >= 0 && P[match + 1] != P[i]) {match = fail[match];}if (P[match + 1] == P[i]) {match++;}fail[i] = match;}
}
bool KMP(char *T, char *P) {  // T 是文本串,P 是匹配串int fail[strlen(P)], match = -1;   // 创建一个长度为 |P| 的数组 failgetFail(P, fail);for (int i = 0; T[i]; ++i) {while (match >= 0 && P[match + 1] != T[i]) {match = fail[match];}if (P[match + 1] == T[i]) {match++;if (!P[match + 1]) {  // P[match + 1] == '\0',就意味着 match 是 P 串的最后一位下标,说明匹配成功return true;}}}return false;
}

Next数组的

#include <iostream>
#include <string.h>
using namespace std;int Next[1110];void get_Next(char *p){int m=strlen(p);Next[0]=Next[1]=0;for(int i=1;i<m;++i){int j=Next[i];while(j&&p[i]!=p[j]){j=Next[j];}Next[i+1]=p[i]==p[j]?j+1:0;}
}int kmp(char *T,char *s){int n=strlen(T),m=strlen(s);get_Next(s);int j=0;for(int i=0;i<n;++i){while(j&&T[i]!=s[j]){j=Next[j];}if(s[j]==T[i]){++j;}if(j==m){return i-m+1;}}return -1;
}int main() {char s[1100],T[1100];cin>>T>>s;cout<<kmp(T,s)<<endl;return 0;
}

字符串算法总结——KMP算法相关推荐

  1. python 求子字符串_(6)KMP算法(求子串的位置)______字符串的匹配

    问题: 已知字符串 B 是字符串 A 的一个子串,问字符串 B 在字符串 A 的第一次出现位置. 暴力方法:从 A 字符串 的每个位置开始对字符串 B 进行匹配. 这种方法根据数据的不同 复杂度不同最 ...

  2. 【数据结构】字符串 模式匹配算法的理解与实现 Brute Force算法(BF算法)与KMP算法 (C与C++分别实现)

    #笔记整理 若不了解串的定义,可至: 串(string)的定义与表示 查看 串的模式匹配算法 求子串位置的定位函数 Index(S, P, pos) 求子串的定位操作通常称作串的模式匹配(其中子串P称 ...

  3. 数据结构与算法之KMP算法

    数据结构与算法之KMP算法 目录 KMP算法介绍 输入字符串str1,str2,返回字符串str2是否在str1中,在的话在第几位开始 1. KMP算法介绍 在CSDN上看到一篇写的很好的关于KMP的 ...

  4. 《数据结构》实验报告四:串的模式匹配(BF算法、KMP算法)

    一.实验目的 1.了解串的基本概念. 2.掌握串的模式匹配算法的实现 . 二.实验预习 说明以下概念 1.模式匹配: 串的模式匹配就是子串的定位运算. 设有两个字符串 S 和 T ,S为主串(正文串) ...

  5. 图解算法:KMP算法

    目录 第一章 暴力匹配实现 第二章 KMP算法介绍 第三章 KMP算法原理 第四章 KMP的匹配表 第五章 KMP算法实现 项目地址:https://gitee.com/caochenlei/algo ...

  6. 【C语言】算法学习·KMP算法

    KMP算法(全称Knuth-Morris-Pratt字符串查找算法,由三位发明者的姓氏命名)是可以在文本串s中快速查找模式串p的一种算法. 要想知道KMP算法是如何减少字符串查找的时间复杂度的,我们不 ...

  7. 数据结构与算法(5)字符串(BF算法、KMP算法及KMP算法优化)

    目录 一.BF算法(暴力算法) 二.KMP算法 三.KMP算法优化 一.BF算法(暴力算法) 一个一个往后匹配,匹配失败继续从母串下一个和头(子串的头)往后继续匹配. 虽然简单,但是需要较多的时间复杂 ...

  8. 字符串处理 —— 单模式匹配 —— MP 算法与 KMP 算法

    [概述] KMP 是在 MP 算法的基础上改进出来的,两者的核心思想与匹配过程相同,唯一不同的是在于 next 数组的求法,其目的是为了避免 MP 算法中明显失败的匹配. KMP 算法又称 Knuth ...

  9. 字符串:3.KMP算法(快速模式匹配算法)详解

    BF算法的改进--KMP算法(快速模式匹配算法). 串的普通模式匹配算法,大体思路是:模式串从主串的第一个字符开始匹配,每匹配失败,主串中记录匹配进度的指针 i 都要进行 i-j+1 的回退操作(这个 ...

  10. python匹配字符串_字符串匹配算法之Kmp算法(Python实现)

    Kmp算法的优势在于它只需要O(m)的与处理时间,而有限状态自动机最快也需要O(m * | Ʃ |).Kmp算法的主要思路跟字符串自动机很像,在预处理阶段建立一个前缀函数,然后顺序扫描文本T,即可找出 ...

最新文章

  1. 线性代数-矩阵-【5】矩阵化简 C和C++实现
  2. 图论 ---- C. Nastya and Unexpected Guest(图上最短路dp + 01bfs)
  3. 非单身勿点,这里是单身汪专属情人节~
  4. struts2学习笔记--使用servletAPI实现ajax的一个小Demo
  5. Windows安装MRTG后的配置
  6. mysql bundle.tar_MySQL 5.6 Bundle Tar安装
  7. php 递归实现无限极分类和排序_Laravel框架实现无限极分类
  8. MyBatis 插件原理与自定义插件-需求实现
  9. Linux中五种压缩命令
  10. web_xml 控制web行为
  11. Ubuntu下安装python3
  12. 在电脑窗口中截取长图/滚动截图
  13. GIS专业书籍、文档、数据、网站、工具等干货
  14. DirectX修复工具强力修复实验包
  15. 做的好不如说得好,老板为什么喜欢听过程汇报?
  16. 股东转让股权的条件是什么
  17. scons 自定义命令行参数传递
  18. C#对XML、JSON等格式的解析
  19. Input输入框如何禁止输入中文
  20. 记一次Rider手写UnityShader_非图解基本的光照模型,包含ViewDir_NdotL高光和漫反射等等计算

热门文章

  1. 微信小程序开发之视频播放器 Video 弹幕 弹幕颜色自定义
  2. 靶机系列-----medium_socnet
  3. c 微信项目开发多语言切换,微信小程序实现多国语言的切换
  4. cvcvtcolor,opencv函数cvcvtcolor和cvtcolor之间的区别是什么
  5. 高考志愿app有哪些
  6. 借助多标签分类器进行对抗训练
  7. smtplib python_python模块smtplib学习
  8. 基于JAVA快滴预约平台计算机毕业设计源码+数据库+lw文档+系统+部署
  9. Dijkstra求最长路就是个坑!
  10. 支付宝小程序跳转H5连接(无需添加白名单)