总算把这个东西搞懂了......

KMP是一个求解字符串匹配问题的算法。

这个东西的核心是一个\(next\)数组,\(next_i\)表示字符串第\(0\sim i\)项的相同的前缀和后缀的最大长度。

这里的前缀和后缀概念略有不同,如 DUCK的前缀为 D,DU,DUC,后缀为 K,CK,UCK,不包含 DUCK本身。

再举一个例子,假设有字符串 DUCKDUCK,则相同的前缀和后缀的最大为 DUCK,因此\(next_7\)值为 \(4\)。

那么怎么求解呢?

对于\(i\),我们知道了\(S_{0\sim next_{i-1}-1}\)和\(S_{i-next_i-1\sim i-1}\)是一样的,如果\(S_{next_{i-1}}=S_i\)就最好,\(next_i=next_{i-1}+1\)。

如果不是怎么办?我们设\(t=next_{i-1}-1\),由于\(S_{0\sim next_{i-1}-1}\)和\(S_{i-next_i-1\sim i-1}\)是一样的,所以在两者的内部,肯定都会有一对长度为\(next_t\)大小的相同的前缀和后缀。

那么,我们考虑新的这个前缀后面等不等于\(s_i\),等于则问题解决,否则故技重施,再找出一个前缀。

可以手动模拟理解一下。

nxt[0]=-1;
for(int i=1;i<m;i++)
{
t=nxt[i-1];
while(t!=-1&&s2[t+1]!=s2[i])t=nxt[t];//前缀不合法,继续找前缀
if(s2[t+1]==s2[i])nxt[i]=t+1;//终于配上了一个前缀
else nxt[i]=-1;//啥也配不上
}

有了这个\(next\)就方便许多了,我们将短的那个字符串的\(next\)算出,如果匹配失败,可以找出前面的,与后缀一样的部分,顶上来匹配,节省时间。

时间复杂度是\(O(|S|)\)的,也就是\(O(n)\)级别。

int i=0,j=0;
while(i<n)
{
if(s[i]==s2[j])
{
i++,j++;
if(j==m)
{
cout<<i-m+1<<endl;
j=nxt[j-1]+1;
}
}
else
{
if(j==0)i++;
else j=nxt[j-1]+1;
}
}

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

  1. C / C++算法学习笔记(8)-SHELL排序

    原始地址:C / C++算法学习笔记(8)-SHELL排序 基本思想 先取一个小于n的整数d1作为第一个增量(gap),把文件的全部记录分成d1个组.所有距离为dl的倍数的记录放在同一个组中.先在各组 ...

  2. Manacher算法学习笔记 | LeetCode#5

    Manacher算法学习笔记 DECLARATION 引用来源:https://www.cnblogs.com/grandyang/p/4475985.html CONTENT 用途:寻找一个字符串的 ...

  3. Johnson算法学习笔记

    \(Johnson\)算法学习笔记. 在最短路的学习中,我们曾学习了三种最短路的算法,\(Bellman-Ford\)算法及其队列优化\(SPFA\)算法,\(Dijkstra\)算法.这些算法可以快 ...

  4. 某科学的PID算法学习笔记

    最近,在某社团的要求下,自学了PID算法.学完后,深切地感受到PID算法之强大.PID算法应用广泛,比如加热器.平衡车.无人机等等,是自动控制理论中比较容易理解但十分重要的算法. 下面是博主学习过程中 ...

  5. Johnson 全源最短路径算法学习笔记

    Johnson 全源最短路径算法学习笔记 如果你希望得到带互动的极简文字体验,请点这里 我们来学习johnson Johnson 算法是一种在边加权有向图中找到所有顶点对之间最短路径的方法.它允许一些 ...

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

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

  7. 算法学习笔记——sort 和 qsort 提供的快速排序

    这里存放的是笔者在学习算法和数据结构时相关的学习笔记,记录了笔者通过网络和书籍资料中学习到的知识点和技巧,在供自己学习和反思的同时为有需要的人提供一定的思路和帮助. 从排序开始 基本的排序算法包括冒泡 ...

  8. KMP算法学习

    kmp算法完成的任务是:给定两个字符串O和f,长度分别为n和m,判断f是否在O中出现,如果出现则返回出现的位置.常规方法是遍历a的每一个位置,然后从该位置开始和b进行匹配,但是这种方法的复杂度是O(n ...

  9. KMP 算法 学习 整理

    我自己整理的KMP算法的PDF文件:http://pan.baidu.com/s/1o8yKIi2提取密码:8291 别的就不多说啥了,感谢来自海子 博客园的 资料--

  10. KMP算法学习(详解)

    kmp算法又称“看毛片”算法,是一个效率非常高的字符串匹配算法.不过由于其难以理解,所以在很长的一段时间内一直没有搞懂.虽然网上有很多资料,但是鲜见好的博客能简单明了地将其讲清楚.在此,综合网上比较好 ...

随机推荐

  1. Java VSCode 基础教学

    VSCode 超全设置1.下载2.插件安装3.项目创建4.设置5.快捷键6.优化7.导出 Jar 包 VSCode 超全设置 VSCode(Visual Studio Code) 是一款 Micros ...

  2. Leecode 1.两数之和(Java 哈希表)

    想法: 1.哈希表hashmap 第一种方法:将数组中元素及其下标right都加入hashmap中,对于每个元素n下标left,在map中查找是否有target-n的元素,若有,则返回其下标right ...

  3. 2022.07.13 vue3下pinia的简单使用及持久化

    使用前说明: 当前demo使用了vue3 + vite + typescript + pinia搭建的简单项目,主要介绍了在单文件组件(sfc)基础上使用pinia的用法,懒得看api的兄弟们,来这瞅 ...

  4. ios装包

    一.下载爱思助手 二.找到本机设备 注:如果未弹出允许.拒绝调试选项可尝试换根数据线解决 三.将对应包体文件拖入本机设备

  5. xlwings读取一整个excel文件xlsx的第一sheet到pandas.DataFrame的方法

    为什么不用:pd.read_excel ? 因为 pd 使用 openpyxl 读取excel文件,有时候xlsx文件是由ApachIO产生的读取进去会出错,换个方式,用xlwings(基于pywin ...

  6. 把OSC_IN/OSC_OUT引脚作为GPIO端口PD0/PD1

    外部振荡器引脚OSC_IN/OSC_OUT可以用做GPIO的PD0/PD1,通过设置复用重映射和调试I/O配置寄存器(AFIO_MAPR)实现.这个重映射只适用于36. 48和64脚的封装(100脚和 ...

  7. kali 配置apt源、设置中文、安装googlepinyin输入法

    配置apt源地址 kali 自带的apt源是国外的,更新网速很慢,这里我设置的是中科大的源. http://mirrors.ustc.edu.cn/help/kali.html 1.复制页面的源地址 ...

  8. Android Studio报错--Build failed with an exception.

    错误描述 在代码写好之后,点击运行,会爆出这样的错误,查看日志,发现是Manifest.xml文件爆出来的错误 具体解决 我的错误没有别的版本那么麻烦,就是我建立了Empty Activity之后,我 ...

  9. SpringBoot笔记--配置文件分类+yaml相关知识+读取配置文件内容

    配置文件 要是需要使用自己的配置替换默认配置时,需要使用后缀名为application.properties或者application.yml(application.yaml)进行配置 当然,几个文 ...

  10. Spring--案例:百度网盘密码数据兼容处理

    案例再度来袭 也就是说,在百度网盘的密码复制时,后面即使有空格也能提取成功(trim方法) 案例的实现: 也就是实现存在空格时,也能输出true: 现在的话: 那么,我们应该如何使得它忽略空格呢? 这 ...