flag:字符串小结。

模式串匹配,顾名思义,就是看一个串是否在另一个串中出现,出现了几次,在哪个位置出现;

p.s.  模式串是前者,并且,我们称后一个 (也就是被匹配的串)为文本串;

  在这篇博客的代码里,s1均为文本串,s2均为模式串;

  一般地,文本串长度不小于匹配串;(否则无意义)

很显然可以得到一个暴力的做法 :

for i : ~lenth_of_s1 {//枚举匹配串在文本串中的开始位置
for j : ~lenth_of_s2
if(s2[j]!=s1[i+j-]) break;
if j>lenth_of_s2 //在循环结束前没有break
output : i
}

时间复杂度:O ( TLE )  ------     O (N+M) ~ O(N*M)

所以需要一个更优的算法;

可以发现,在枚举匹配串在文本串中的开始位置时,有很多步骤是无效的,因为匹配串的第一个字符 很有可能和当前枚举到的开始位置 不同;

所以可以优化这个过程,每次改变开始位置时,直接移动到下一个和匹配串第一个字符相同的位置 (类似于链表;

int next[N], pos=-;
char head = s2[]; for i : lenth_of_s1~
if s1[i]==head {
next[i] = pos;
pos = i;
}
next[] = pos; for i = next[] ; i != - ; i = next[i] {
for j : ~lenth_of_s2
if(s2[j]!=s1[i+j-]) break;
if j>lenth_of_s2 //在循环结束前没有break
output : i
}

这个做法看起来很强,实际上很容易被卡成O (n^2);

比如说 :s1 :sssssssssssssa, s2 : sssb;

由于并没有利用所有已经匹配过的部分,所以仍然会T;

于是,就有了KMP算法。

p.s.  i表示当前在文本串中枚举到的位置,j表示模式串中的;

在s1[ i ] != s2 [ j ]时,将 j 移动到一个在 j 之前的位置k 使得 s2[ 1 ]~s2[ k ] 与 s2[ j-k+1 ]~s2[ j ]完全相同,那么时间复杂度就是O (N+M) 的了;

p.s.  因为 i , j 两个指针最多移动N+M次;

给一个写模板的链接 :https://www.luogu.org/problemnew/show/P3375

贴代码 :

// luogu-judger-enable-o2
// 15owzLy1
//luogu3375_kmp.cpp
//2018 10 02 17:27:50
#include <cstdio>
#include <cstring>
typedef long long ll;
typedef double db;
using namespace std; const int N = ;
int next[N], la, lb;
char a[N], b[N]; template<typename T>inline void read(T &x_) {
x_=;bool f_=;char c_=getchar();
while(c_<''||c_>''){f_|=(c_=='-');c_=getchar();}
while(c_>=''&&c_<=''){x_=(x_<<)+(x_<<)+(c_^);c_=getchar();}
x_=f_?-x_:x_;
} inline void get_next() {
int j=;
for(int i=;i<=lb;i++) {
while(j&&b[j+]!=b[i]) j=next[j];
if(b[j+]==b[i]) ++j;
next[i]=j;
}
} inline void kmp() {
int j=;
for(int i=;i<=la;i++) {
while(j&&a[i]!=b[j+]) j=next[j];
if(b[j+]==a[i]) ++j;
if(j==lb)
printf("%d\n", i-j+);
}
} int main() {
#ifndef ONLINE_JUDGE
freopen("luogu3375_kmp.in","r",stdin);
freopen("luogu3375_kmp.out","w",stdout);
#endif
scanf("\n%s%s", a+, b+); la=strlen(a+), lb=strlen(b+);
get_next();
kmp();
for(int i=;i<=lb;i++) printf("%d ", next[i]);
puts("");
return ;
}
												

单模式串匹配----浅谈kmp算法的更多相关文章

  1. 浅谈KMP算法及其next[]数组

    KMP算法是众多优秀的模式串匹配算法中较早诞生的一个,也是相对最为人所知的一个. 算法实现简单,运行效率高,时间复杂度为O(n+m)(n和m分别为目标串和模式串的长度) 当字符串长度和字符集大小的比值 ...

  2. 浅谈KMP算法

    一.介绍 烤馍片KMP算法是用来处理字符串匹配问题的.比如说给你两个字符串A,B,问B是不是A的子串? 比如,eg就是aeggx的子串 一般讲字符串A称为主串,用来匹配的B串称为模式串 定义n为字符串 ...

  3. 【字符串算法3】浅谈KMP算法

    [字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述  [字符串算法3]KMP算法 Part1 理解KMP的精髓和思想 其实KM ...

  4. 浅谈KMP算法——Chemist

    很久以前就学过KMP,不过一直没有深入理解只是背代码,今天总结一下KMP算法来加深印象. 一.KMP算法介绍 KMP解决的问题:给你两个字符串A和B(|A|=n,|B|=m,n>m),询问一个字 ...

  5. 【文文殿下】浅谈KMP算法next数组与循环节的关系

    KMP算法 KMP算法是一种字符串匹配算法,他可以在O(n+m)的时间内求出一个模式串在另一个模式串下出现的次数. KMP算法是利用next数组进行自匹配,然后来进行匹配的. Next数组 Next数 ...

  6. 浅谈 KMP 算法

    最近在复习数据结构,学到了 KMP 算法这一章,似乎又迷糊了,记得第一次学习这个算法时,老师在课堂上讲得唾沫横飞,十分有激情,而我们在下面听得一脸懵比,啥?这是个啥算法?啥玩意?再去看看书,完全听不懂 ...

  7. 浅谈分词算法(5)基于字的分词方法(bi-LSTM)

    目录 前言 目录 循环神经网络 基于LSTM的分词 Embedding 数据预处理 模型 如何添加用户词典 前言 很早便规划的浅谈分词算法,总共分为了五个部分,想聊聊自己在各种场景中使用到的分词方法做 ...

  8. 浅谈分词算法(4)基于字的分词方法(CRF)

    目录 前言 目录 条件随机场(conditional random field CRF) 核心点 线性链条件随机场 简化形式 CRF分词 CRF VS HMM 代码实现 训练代码 实验结果 参考文献 ...

  9. 浅谈分词算法(3)基于字的分词方法(HMM)

    目录 前言 目录 隐马尔可夫模型(Hidden Markov Model,HMM) HMM分词 两个假设 Viterbi算法 代码实现 实现效果 完整代码 参考文献 前言 在浅谈分词算法(1)分词中的 ...

随机推荐

  1. Linux内核入门到放弃-模块-《深入Linux内核架构》笔记

    使用模块 依赖关系 modutils标准工具集中的depmod工具可用于计算系统的各个模块之间的依赖关系.每次系统启动时或新模块安装后,通常都会运行该程序.找到的依赖关系保存在一个列表中.默认情况下, ...

  2. Luogu5176 公约数 莫比乌斯反演、线性筛

    传送门 好像是我们联考时候的题目? 一个结论:\(\gcd(ij,ik,jk) \times \gcd(i,j,k) = \gcd(i,j) \times \gcd(i,k) \times \gcd( ...

  3. python之configparser模块详解--小白博客

    configparse模块 一.ConfigParser简介 ConfigParser 是用来读取配置文件的包.配置文件的格式如下:中括号“[ ]”内包含的为section.section 下面为类似 ...

  4. Python是如何实现生成器的原理

    python中函数调用的实质原理: python解释器(即python.exe)其实是用C语言编写的, 在执行python代码时,实际上是在用一个叫做Pyeval_EvalFramEx(C语言的函数) ...

  5. CSL 的魔法

    链接 [https://ac.nowcoder.com/acm/contest/551/E] 分析 很显然就是a的第k大得和b的倒数第k大相乘. 那么我们只要让a的第k大和b的倒数第k大位置是相同的即 ...

  6. 使用IDEA2017在Windows下编程并测试Hadoop2.7+Spark2.2+Azkaban

    1. 下载好IDEA HADOOP SPARK 首先,配置IDEA, 在插件管理中使用IDEA在线库安装scala插件, 在在线库直接搜索即可; 其次,配置Maven选项, 将Maven添加到IDEA ...

  7. vue 限制输入字符长度

    一.watch方法: <input v-model="textareaValue" type="textarea" placeholder="请 ...

  8. 下载图片没有关闭http输入流导致下载超时

    在某次接入第三方厂商数据时,需要根据对方提供的URL地址下载图片,当数据量大时会遇到很多的下载图片超时问题,开始以为是第三方厂商的问题,对方排查了很久之后,说是我这边下载数据全部留在缓存区,导致缓存区 ...

  9. BZOJ4269再见Xor——高斯消元解线性基

    题目描述 给定N个数,你可以在这些数中任意选一些数出来,每个数可以选任意多次,试求出你能选出的数的异或和的最大值和严格次大值. 输入 第一行一个正整数N. 接下来一行N个非负整数. 输出 一行,包含两 ...

  10. 读zepto源码之工具函数

    读zepto源码之工具函数 Zepto 提供了丰富的工具函数,下面来一一解读. 源码版本 本文阅读的源码为 zepto1.2.0 $.extend $.extend 方法可以用来扩展目标对象的属性.目 ...