KMP 算法是用来处理字符串匹配问题的。也就是给你两个字符串,你需要回答:B 串是否是 A 串的子串(或 B 串在 A 串中出现的位置)。比如,字符串 A = “ i am student ”, 字符串 B = “ student ”,我们就说 B 是 A 的子串。我们称待匹配的 A 串为匹配串,用来匹配的 B 串为模式串。

如果使用普通的暴力枚举的算法,遇到个极端的例子,比如 abababababababaab 和 aab,匹配的时间复杂度会高到难以承受,为 O(nm),其中 n 为匹配串的长度,m 为模式串的长度。如果使用 KMP 算法,最坏的情况下,时间复杂度也只会是 O(n + m)。

(此处省略讲解过程,等以后再补Orz)算了我知道我是不可能补得上的

下面 KMP 算法的代码模板(注意,这里的 fail 数组是从 - 1 开始的)

 #include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + ; string s, t;
int fail[maxn]; void get_fail(string x) {
int i = , j = -;
fail[] = -;
while (x[i]) {
if (j == - || x[i] == x[j]) {
fail[++i] = ++j;
} else {
j = fail[j];
}
}
} int kmp(string x, string y) {
get_fail(y);
int i = , j = , res = ;
int m = y.size();
while (x[i]) {
if (x[i] == y[j]) {
++i;
++j;
if (!y[j]) {
++res;
cout << i - m + << endl; // 输出模式串在匹配串中出现的位置(从1开始计数)
j = fail[j]; // 匹配部分可以重叠,如果不可以重叠则直接 j = 0;
}
} else {
j = fail[j];
if (j == -) {
++i;
++j;
}
}
}
return res; // 这里返回的 res 代表模式串在匹配串中出现的次数
} int main() {
cin >> s >> t;
cout << kmp(s, t) << endl;
return ;
}

学习 KMP 算法的更多相关文章

  1. 学习KMP算法的一点小心得

    KMP算法应用于 在一篇有n个字母的文档中 查找某个想要查找的长度为m的单词:暴力枚举:从文档的前m个字母和单词对比,然后是第2到m+1个,然后是第3到m+2个:这样算法复杂度最坏就达到了O(m*n) ...

  2. 【2018.07.27】(字符串/找相同)学习KMP算法小记

    虽然说原理很好理解,但是代码理解了花费我一个下午的时间,脑阔痛 该注释的地方都标记了,希望以后看到这些代码我还能好好理解吧 学习的链接地址:https://www.cnblogs.com/teble/ ...

  3. 学习KMP算法

    int kmp(char * t,int lenT,char * pat,int lenPat){ ,posT=; int[] f=partialMatch(pat,lenPat)//获取pat字符串 ...

  4. KMP算法(研究总结,字符串)

    KMP算法(研究总结,字符串) 前段时间学习KMP算法,感觉有些复杂,不过好歹是弄懂啦,简单地记录一下,方便以后自己回忆. 引入 首先我们来看一个例子,现在有两个字符串A和B,问你在A中是否有B,有几 ...

  5. KMP算法具体解释

    这几天学习kmp算法,解决字符串的匹配问题.開始的时候都是用到BF算法,(BF(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配 ...

  6. 运用kmp算法解决的一些问题的简单题解

    学习kmp算法我最后是看的数据结构书上的一本教材学会的..我认为kmp相对于普通的BF算法就是避免了非常多不必要的匹配.而kmp算法的精髓自然就在于next数组的运用...而next数组简而言之就是存 ...

  7. LA 3026 && POJ 1961 Period (KMP算法)

    题意:给定一个长度为n字符串s,求它每个前缀的最短循环节.也就是对于每个i(2<=i<=n),求一个最大整数k>1(如果存在),使得s的前i个字符组成的前缀是某个字符串重复得k次得到 ...

  8. KMP算法,查询匹配串的个数

    想不到时隔两年回来重新学习KMP算法还是那么难,不过理解了大概,把例程贴上来,如果是求数量只需要加个count变量记录即可. #include"stdio.h" #include& ...

  9. KMP算法的一个简单实现

    今天学习KMP算法,参考网上内容,实现算法,摘录网页内容并记录自己的实现如下: 原文出处: http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93M ...

随机推荐

  1. POJ1044 Date bugs

    题目来源:http://poj.org/problem?id=1044 题目大意: 与众所周知的”千年虫“类似,某些计算机上存在日期记录的bug.它们的时钟有一个年份周期,每当到达最大值时,就会自动跳 ...

  2. vue——运行一个项目

    教程:https://segmentfault.com/a/1190000009871504 启动:cnpm run dev

  3. android 缓存路径

    用程序在运行的过程中如果需要向手机上保存数据,一般是把数据保存在SDcard中的.大部分应用是直接在SDCard的根目录下创建一个文件夹,然后把数据保存在该文件夹中.这样当该应用被卸载后,这些数据还保 ...

  4. Babelfish (关于map<string,string>的用法

    题目链接:https://vjudge.net/contest/237395#problem/A 学习博客:https://blog.csdn.net/lyy289065406/article/det ...

  5. arch安装软件提示包损坏

    错误:lib32-libjpeg6-turbo: signature from "Colin Keenan <colinnkeenan@gmail.com>" is u ...

  6. 《从0到1学习Flink》—— Flink 写入数据到 Kafka

    前言 之前文章 <从0到1学习Flink>-- Flink 写入数据到 ElasticSearch 写了如何将 Kafka 中的数据存储到 ElasticSearch 中,里面其实就已经用 ...

  7. SpringBoot | 第七章:过滤器、监听器、拦截器

    前言 在实际开发过程中,经常会碰见一些比如系统启动初始化信息.统计在线人数.在线用户数.过滤敏高词汇.访问权限控制(URL级别)等业务需求.这些对于业务来说一般上是无关的,业务方是无需关系的,业务只需 ...

  8. C# 多线程之线程池

    线程池System.Threading.ThreadPool,可用于发送工作项.处理异步I/O.代表其它线程等待以及处理计时器.基本用法: public void Main() { ThreadPoo ...

  9. StringMVC返回字符串

    @RequestMapping(value="twoB.do") public void twoBCode(HttpServletRequest request,HttpServl ...

  10. CF1182E Product Oriented Recurrence

    思路: fn = can * f1xn * f2yn * f3zn, 首先dp计算指数部分an = an-1 + an-2 + an-3 + 2 * n - 6, 而an-1 = an-2 + an- ...