题目描述

给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字。

模板串P在模式串S中多次作为子串出现。

求出模板串P在模式串S中所有出现的位置的起始下标。

输入格式

第一行输入整数N,表示字符串P的长度。

第二行输入字符串P。

第三行输入整数M,表示字符串S的长度。

第四行输入字符串M。

输出格式

共一行,输出所有出现位置的起始下标(下标从0开始计数),整数之间用空格隔开。

数据范围

1≤N≤10^4
1≤M≤10^5

输入样例:

3
aba
5
ababa
输出样例:

0 2

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 100010, M = 1000010;
int n, m, i, j, ne[N];
char p[N], s[M];
int main()
{ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin >> n >> p + 1 >> m >> s + 1;for(i = 2, j = 0; i <= n; i++){while(j && p[i] != p[j + 1])j = ne[j];if(p[i] == p[j + 1])j++;ne[i] = j;}for(i = 1, j = 0; i <= m; i++){while(j && s[i] != p[j + 1])j = ne[j];if(s[i] == p[j + 1])j++;if(j == n){cout << i - n << ' ';j = ne[j];}}return 0;
}

思想和理解

时间复杂度
kmp算法的本质就是优化,让效率更高,暴力也可以做出这题,但是太慢了,时间复杂度会达到O(n*m),使用了kmp算法后,我们就可以把时间复杂度优化到O(n+m)
定义
模式串S:可以简单理解为较长的那个串,设长度为m
模板串P:可以简单理解为较短的那个串,设长度为n
next数组
kmp算法优化的关键,就是next数组。这个数组可以让我们在模板串对模式串匹配失败时,可以不用从头遍历模板串,而是对模板串进行“回跳”。
对于next数组的理解(这里为了避免和头文件里其他给定的结构冲突,用ne表示)

ne[i]=j;

这一行代码的意思是:从下标i-j+1到i的序列,等于从1到j的序列(设序列从1开始)。我们也可以理解为,i为序列后缀的最后一个元素下标,j为序列前缀的最后一个元素下标,该前缀和后缀相等。
我们来画个图直观理解一下:

这样,如果我们的P和S匹配失败的话,就可以用ne数组的操作来“回跳”,而不用从头遍历P了。

字符串匹配过程

kmp算法的核心操作有两个:预处理next的数组,字符串匹配。在代码实现方面,预处理next数组和字符串匹配基本相同,所以我们先讲解字符串匹配的代码,然后复制粘贴,再稍作修改,我们就可以得到next数组预处理的代码了。

for(i = 1, j = 0; i <= m; i++){while(j && s[i] != p[j + 1])j = ne[j];if(s[i] == p[j + 1])j++;if(j == n){cout << i - n << ' ';j = ne[j];}}

首先解释为什么要s[i]和p[j+1]匹配。因为如果我们检测到s[i]和p[j+1]不匹配的话,那就证明p[j]和s[i]是匹配的,这样我们让j=ne[j]才有意义,否则如果检测出s[i]和p[j]不匹配,然后再让j-1=ne[j-1]就会很麻烦,代码阅读性不如j+1这个方案好。(我个人理解)
让i从1开始也是同样的道理,可以简化编程和阅读的难度。

预处理next数组过程

代码:

    for(i = 2, j = 0; i <= n; i++){while(j && p[i] != p[j + 1])j = ne[j];if(p[i] == p[j + 1])j++;ne[i] = j;}

重点理解一下ne[i]=j
画图如下:

当j++后,此时的p[i]是等于p[j]的,也就是相当于,从1到j的序列等同于从i-j+1到i的序列,这时我们就可以把ne[i]的值赋值为j。

介绍KMP算法思想(例题:ACWING 831 kmp字符串)相关推荐

  1. 3000+长文带你进入KMP算法思想

    1. 基本介绍 原文最先在博客园发布,原地址:3000+长文带你进入KMP算法思想 1.1 说明 时间复杂度: O ( N ) O(N) O(N): 空间复杂度: O ( N ) O(N) O(N): ...

  2. 完全掌握KMP算法思想

    文档下载页面http://download.csdn.net/detail/yedeqixian/4209500       80页在讲KMP算法的开始先举了个例子,让我们对KMP的基本思想有了最初的 ...

  3. 【KMP算法详解——适合初学KMP算法的朋友】

    相信很多人(包括自己)初识KMP算法的时候始终是丈二和尚摸不着头脑,要么完全不知所云,要么看不懂书上的解释,要么自己觉得好像心里了解KMP算法的意思,却说不出个究竟,所谓知其然不知其所以然是也. 经过 ...

  4. 比KMP算法更简单更快的字符串匹配算法

    我想说一句"我日,我讨厌KMP!". KMP虽然经典,但是理解起来极其复杂,好不容易理解好了,便起码来巨麻烦! 老子就是今天图书馆在写了几个小时才勉强写了一个有bug的.效率不高的 ...

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

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

  6. AcWing 831. KMP字符串(模板)

    给定一个模式串S,以及一个模板串P,所有字符串中只包含大小写英文字母以及阿拉伯数字. 模板串P在模式串S中多次作为子串出现. 求出模板串P在模式串S中所有出现的位置的起始下标. 输入格式 第一行输入整 ...

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

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

  8. KMP算法-next函数介绍

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

  9. 图解KMP算法,带你彻底吃透KMP

    模式串匹配--KMP算法 KMP算法一直是一个比较难以理解的算法,本篇文章主要根据<大话数据结构>中关于KMP算法的讲解,结合自己的思考,对于KMP算法进行一个比较详细的解释. 由于博主本 ...

  10. 三十五、字符串匹配问题--KMP算法

    一.暴力匹配算法实现字符串匹配 如果用暴力匹配的思路,并假设现在 str1 匹配到 i 位置,子串 str2 匹配到 j 位置,则有: 如果当前字符匹配成功(即 str1[i] == str2[j]) ...

最新文章

  1. 两条波浪线符号_四年级数学上册第二单元“线的认识”作业单(附带答案)
  2. Web应用配置虚拟主机(www.baidu.com)
  3. DNS通道检测 国外学术界研究情况——研究方法:基于流量,使用机器学习分类算法居多,也有使用聚类算法的;此外使用域名zif low也有...
  4. centos7离线安装bazel
  5. liferay requestrequest和actionRequest用法
  6. 《潜意识:控制你行为的秘密》摘录
  7. NIO学习–核心概念与基本读写
  8. 转:C++中const、volatile、mutable的用法
  9. 实战oracle 12c 处理索引坏块一例
  10. [外包]!采用asp.net core 快速构建小型创业公司后台管理系统(四.quartz 简单配置使用)...
  11. php在linux中执行外部命令
  12. 算法复杂度O(1),O(n),O(logn),O(nlogn)的区别
  13. 软件系统的测试计划,软件系统测试计划-模板
  14. cad插件苹果系统_CAD看图软件mac版|CAD迷你看图 for Mac下载 v4.0.0 官方版_最火软件站...
  15. 注意力机制的直观理解
  16. 天猫精灵 python_GitHub - zhjc1124/tmallgenius: 天猫精灵打卡
  17. android+系统画面恢复,坚持Android系统恢复?轻松修复它
  18. TJA1043收发器信息梳理
  19. 计算机管理损坏的图像,win7系统提示损坏的图像的解决方法
  20. 【DevOps】持续集成

热门文章

  1. supervisor 管理
  2. 机器学习重塑供应链管理的10个途径
  3. pyCharm-激活码(2018)
  4. MongoDB实战-面向文档的数据(找到最合适的数据建模方式)
  5. C语言描述的数据结构顺序表的置空 slt-size=0含义
  6. SQL Server 2000 Service Pack 4 升级指南
  7. mysql 写出高性能sql 防止索引失效总结
  8. Could not autowire field: XXXXX.
  9. 题解 P1217 【[USACO1.5]回文质数 Prime Palindromes】
  10. 妖(至250线)——善始善终