当前位置: 首页 > article >正文

KMP 详解

KMP数组存的是什么

对于一个字符串 b,下标从1开始。

则kmp[i]表示 以i结尾的连续子串 = s的前缀的最大值(等价于前缀最大结尾处)

如何求KMP

假设 i 以前的KMP都被求出来了。

j 表示上一个字符可以成功匹配的长度(等价于下标)

如果b[j+1] != b[i]下一个位置匹配不上(即不能成为前缀)

则,让j = kmp[j] 即成为以j结尾的 连续子串 的 最长前缀 尾部的下标

退出循环后,若还能匹配上则j++(本质是,加上i的贡献。因为j = 0时可能匹配不上)

然后让kmp[i] = j即可。

运用kmp

和求kmp差不多,如果匹配不上,求让a[i]和以j结尾的连续子串的最长前缀匹配。(放宽要求)

算法正确性证明

用哲学的话来说就是,每一次失败都会让我变得更强大。

当匹配不上时,匹配串b至少会前移1位,由指针的思想。O(n)可证。

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6+7;
int kmp[N];
string a,b;
int j;
int main(){
	cin>>a>>b;
	a = " "+a;
	b = " "+b;
	for(int i = 2;i < b.size();i++){
		while(j&&b[j+1] != b[i]){
			j = kmp[j];
		}
		if(b[j+1] == b[i])j++;
		kmp[i] = j;
	}
	j = 0;
	for(int i = 1;i < a.size();i++){
		while(j&&a[i] != b[j+1]){
			j = kmp[j];
		}
		if(b[j+1] == a[i])j++;
		if(j == b.size()-1){
			cout<<i-(b.size()-1)+1<<endl;
			j=kmp[j];
		}
	}
	for (int i=1;i < b.size();i++)cout<<kmp[i]<<" ";
	return 0;
}

 


http://www.kler.cn/a/292716.html

相关文章:

  • 区块链技术在慈善捐赠中的应用
  • LeetCode【0031】下一个排列
  • 前端知识点---Javascript的对象(Javascript)
  • ISAAC SIM踩坑记录--ubuntu 22.04操作系统安装
  • 【Spring】@Autowired与@Resource的区别
  • 《TCP/IP网络编程》学习笔记 | Chapter 11:进程间通信
  • AI问答:.NET核心组成概要、程序运行步骤和查询SDK版本的方法
  • 使用pytorch深度学习框架搭建神经网络
  • 使用Python中的igraph为绘图添加标题和图例
  • Ventoy启动盘制作
  • 计算机网络10——数据库语法1
  • 【2024数模国赛赛题思路公开】国赛B题第二套思路丨附可运行代码丨无偿自提
  • 数字电子技术-码制
  • 总结24个Python接单赚钱平台与详细教程,兼职月入5000+
  • 视频编码与传输 学习笔记 1 一些视频压缩算法的介绍
  • Android kernel 配置docker
  • 前后端时间正确传递
  • 【扇贝编程】python爬虫——爬取动态网页笔记
  • getent passwd 获取linux并显示用户账户信息
  • 【数据结构-二维前缀异或和】【分区算法优化】力扣1738. 找出第 K 大的异或坐标值
  • CNN的魅力:探索卷积神经网络的无限可能
  • 信息安全--(五)物理与环境安全技术(二)机房安全分析与防护
  • Redis从简单使用到底层原理与分布式缓存
  • STM32外部中断(总结了易出现的BUG)
  • 基于springboot的二手车交易系统的设计与实现
  • 在 Cloud TPU Pod 上训练 PyTorch 模型