P3375 【模板】KMP字符串匹配

news2025/1/23 9:12:54

题目描述

给出两个字符串 s_1s1​ 和 s_2s2​,若 s_1s1​ 的区间 [l, r][l,r] 子串与 s_2s2​ 完全相同,则称 s_2s2​ 在 s_1s1​ 中出现了,其出现位置为 ll。
现在请你求出 s_2s2​ 在 s_1s1​ 中所有出现的位置。

定义一个字符串 ss 的 border 为 ss 的一个非 ss 本身的子串 tt,满足 tt 既是 ss 的前缀,又是 ss 的后缀。
对于 s_2s2​,你还需要求出对于其每个前缀 s's′ 的最长 border t't′ 的长度。

输入格式

第一行为一个字符串,即为 s_1s1​。
第二行为一个字符串,即为 s_2s2​。

输出格式

首先输出若干行,每行一个整数,按从小到大的顺序输出 s_2s2​ 在 s_1s1​ 中出现的位置。
最后一行输出 |s_2|∣s2​∣ 个整数,第 ii 个整数表示 s_2s2​ 的长度为 ii 的前缀的最长 border 长度。

输入输出样例

输入 #1复制

ABABABC
ABA

输出 #1复制

1
3
0 0 1 

说明/提示

样例 1 解释

对于 s_2s2​ 长度为 33 的前缀 ABA,字符串 A 既是其后缀也是其前缀,且是最长的,因此最长 border 长度为 11。

数据规模与约定

本题采用多测试点捆绑测试,共有 3 个子任务

  • Subtask 1(30 points):|s_1| \leq 15∣s1​∣≤15,|s_2| \leq 5∣s2​∣≤5。
  • Subtask 2(40 points):|s_1| \leq 10^4∣s1​∣≤104,|s_2| \leq 10^2∣s2​∣≤102。
  • Subtask 3(30 points):无特殊约定。

对于全部的测试点,保证 1 \leq |s_1|,|s_2| \leq 10^61≤∣s1​∣,∣s2​∣≤106,s_1, s_2s1​,s2​ 中均只含大写英文字母。

 

 1.这个题目用到了KMP算法。

2.刚开始我写的是KMP算法,但是后面只AC了三个,其他都TLE了,我就开始寻求优化。

3.我们通常写的KMP算法,我发现每次都需要取判断母串和子串是否相等,再去判断不相等的情况,我们可以知道,如果是相等的情况,我们是可以开循环继续往下比较的,不必在主循环消耗时间,出来之后肯定是遇到了子串和母串不相等的情况,此时我们可以先判断是否子串已经走完,我们可以输出位置。

4.继而就是,令他往回靠近,也就是j=nex[j-1],还有一个情况是如果  j  在子串一直是  0  的位置,而且此时子串和母串是不相等的情况,我们可以一直让 i++,使它到能够相等的情况。

5.在处理next数组时我们也可以使用这种方法。

C代码如下:

#include<stdio.h>
#include<string.h>
#define N 1000010
char s1[N],s2[N];
int nex[N],n,m;
int next()
{
	int i,j=0;
	for(i=1;i<n;)
	{
		while(s2[i]==s2[j])
		{
			j++;
			nex[i]=j;
			i++;
		}
		j=nex[j-1];
		while(j==0&&s2[i]!=s2[j]) i++;
	}
	return 0;
}
int kmp()
{
	int i,j=0;
	next();
	for(i=0;i<n;)
	{
	//	puts("*");
		while(s1[i]==s2[j]&&j<m)
		{
			i++;
			j++;
		}
		if(j>=m) printf("%d\n",i-m+1);
		j=nex[j-1];
		while(j==0&&s1[i]&&s1[i]!=s2[j]) i++;
	}
	return 0;
}
int main()
{
	scanf("%s%s",s1,s2);
	n=strlen(s1),m=strlen(s2);
	kmp();
	for(int i=0;s2[i];i++)
	{
		printf("%d ",nex[i]);
	}
	return 0;
}

C++代码如下:

#include<iostream>
#include<bits/stdc++.h>
#include<cstring>

using namespace std;

const int N=1000010;

char s1[N],s2[N];
int nex[N],n,m;
int next()
{
	int i,j=0;
	for(i=1;i<n;)
	{
		while(s2[i]==s2[j])
		{
			j++;
			nex[i]=j;
			i++;
		}
		j=nex[j-1];
		while(j==0&&s2[i]!=s2[j]) i++;
	}
	return 0;
}
int kmp()
{
	int i,j=0;
	next();
	for(i=0;i<n;)
	{
		while(s1[i]==s2[j]&&j<m)
		{
			i++;
			j++;
		}
		if(j>=m) cout << i-m+1 << endl;
		j=nex[j-1];
		while(j==0&&s1[i]&&s1[i]!=s2[j]) i++;
	}
	return 0;
}
int main()
{
	cin >> s1 >> s2;
	n=strlen(s1),m=strlen(s2);
	kmp();
	for(int i=0;s2[i];i++)
	{
		cout << nex[i] << " ";
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/151427.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

概率论【离散型二维变量与连续性二维变量(上)】--猴博士爱讲课

5.离散型二维变量与连续性二维变量&#xff08;上&#xff09; 1/8 已知二维离散型分布律&#xff0c;求??? 离散型直接看表 【做题方法参考如下】 2/8 已知二维离散型分布律&#xff0c;判断独立性 如果满足p(xy) p(x) * p(y)&#xff0c;那么相互独立 则我们只需要验证每…

C 程序设计教程(12)—— C 语言顺序结构程序设计

C 程序设计教程&#xff08;12&#xff09;—— C 语言顺序结构程序设计 该专栏主要介绍 C 语言的基本语法&#xff0c;作为《程序设计语言》课程的课件与参考资料&#xff0c;用于《程序设计语言》课程的教学&#xff0c;供入门级用户阅读。 目录C 程序设计教程&#xff08;1…

深入探索Flutter性能优化

前言 Flutter 作为目前最火爆的移动端跨平台框架&#xff0c;能够帮助开发者通过一套代码库高效地构建多平台的精美应用&#xff0c;并支持移动、Web、桌面和嵌入式平台。对于 Android 来说&#xff0c;Flutter 能够创作媲美原生的高性能应用&#xff0c;但是&#xff0c;在较…

【nvivo11plus教程】02_编码与节点

1、对文档进行编码(1)建立节点(2)使用快速编码栏进行编码(3)将整个文件编码为一个代码(4)范围编码(5)在vivo中编码(6)使用节点昵称加快编码速度2、取消、增加和查看编码(1)编码带(2)删除编码(3)查看编码邻近区(4)增加编码(5)查看编码信息3、组织节点(1)节点结构化(2)移动归类节…

leetcode-每日一题-还原排列的最少操作步数(中等,数学逻辑)

回家了很少看了&#xff0c;今天突然心血来潮做了今天的每日一题&#xff0c;还不错&#xff0c;最后是一次AC&#xff0c;说明这么长时间没看实力没有下降多少&#xff0c;哈哈哈哈&#xff0c;自恋一下&#xff0c;后面我会更新一些课设和实验作业&#xff0c;进入正题。给你…

密码学_ECC椭圆曲线加密算法

算法介绍 椭圆加密算法&#xff08;ECC&#xff09;是一种公钥加密体制&#xff0c;最初由Koblitz和Miller两人于1985年提出&#xff0c;其数学基础是利用椭圆曲线上的有理点构成Abel加法群上椭圆离散对数的计算困难性。公钥密码体制根据其所依据的难题一般分为三类&#xff1a…

【jQuery】常用API——jQuery样式操作

一、操作 css 方法 jQuery 可以使用 css 方法来修改简单元素样式。1. 参数只写属性名&#xff0c;则是返回属性值$(this).css(color);2. 参数是属性名&#xff0c;属性值&#xff0c;逗号分隔&#xff0c;是设置一组样式&#xff0c;属性必须加引号&#xff0c;值如果是数字可以…

Go基础学习

文章目录回看下历史环境安装和开发工具&#xff1a;基础语法&#xff1a;go的注释&#xff1a;变量定义&#xff1a;简短定义模式Go的变量交换匿名变量&#xff08;空白标识符&#xff09;&#xff1a;变量的作用域&#xff1a;iota常量计数器数据类型布尔类型数值型整数浮点数…

新冠COVIN-19流感病患轨迹追溯

实验背景 冬季是流感的高发季节&#xff0c;现已知某流感病毒的传播力很强&#xff0c;政府部门也陆续公开了部分流感确诊患者&#xff08;后续简称“病患”&#xff09;的非隐私信息&#xff0c;这部分数据为相关研究人员研究该流感病毒的传播与防控提供了重要的数据支撑。 然…

Linux网站服务实操练习

作者简介&#xff1a;一名99年软件运维应届毕业生&#xff0c;正在自学云计算课程。宣言&#xff1a;人生就是B&#xff08;birth&#xff09;和D&#xff08;death&#xff09;之间的C&#xff08;choise&#xff09;&#xff0c;做好每一个选择。创作不易&#xff0c;动动小手…

python:打包package

简介 把模块打包成package&#xff0c;可以进行分发和安装。 packaged的打包和安装一、package层次架构二、 package的打包和安装1. 创建setup.py2. 打包package3. 安装package一、package层次架构 其中mypackage为进行打包的文件夹&#xff0c;文件夹下包含多个脚本&#xff1…

钢铁行业应用APS生产排产系统的好处

1 钢铁行业APS生产排产系统设计的主要业务流程 全局一体化计划&#xff1a;主要负责订单交期评审与应答、销产转换、主生产计划、铁水需求计划&#xff0c;该计划的最终目标是对各个分厂的日计划提出整体要求。主要对口业务部门为公司生产计划排程部门。 各个工段厂区的一体化…

SpringCloud微服务项目实战 - 4.自媒体平台(博主后台)

“我读过很多书&#xff0c;但后来大部分都忘记了&#xff0c;你说这样的阅读究竟有什么意义&#xff1f;” “当我还是个孩子时&#xff0c;我吃过很多食物&#xff0c;现在已经记不起来吃过什么了。但可以肯定的是&#xff0c;它们中的一部分已经长成我的骨头和肉。” 系列文…

LaoCat带你认识容器与镜像(三【上】)

有道是每逢佳节倍惰怠 ~&#xff0c;春节期间随缘更新吧 ~ 本章内容 Docker挂载数据卷相关。 本文实操全部基于Ubuntu 20.04 宿主机 > linux服务器本身 前边章节就介绍过Docker数据卷相关的知识点&#xff0c;也特别强调了生产环境一定要记得挂载数据卷&#xff0c;编程的小…

【前端】Vue项目:旅游App-(11)city:添加热门数据、动态修改索引栏、点击跳转、显示城市

文章目录目标过程与代码添加热门数据热门数据样式索引栏索引监听点击、保存数据、回退首页跳转到city页、显示城市效果总代码修改的文件city.jscurrentGroupCity.vuehome.vue目标 上一篇以indexBar的形式显示了数据&#xff1a;【前端】Vue项目&#xff1a;旅游App-&#xff0…

【Kubernetes 企业项目实战】01、使用 kubeadm 安装 K8s-v1.23 高可用集群

目录 K8s-v1.23 安装环境规划 kubeadm 和二进制安装 k8s 适用场景分析 一、初始化安装 k8s 集群的环境 1.1 初步的环境初始化 1.2 配置主机之间无密码登录 1.3 关闭交换分区 swap 提升性能 1.4 修改机器内核参数 1.5 配置阿里云的 repo 源 1.6 配置安装 k8s 组件需要…

python调试器 ipdb

文章目录1. 介绍1.1 常用调试方式1.2 安装 ipdb2. 用法3. 命令3.1、查看源代码3.2、添加断点3.3 添加临时断点3.4 清除断点3.5、打印变量值3.6、逐行调试命令3.7、非逐行调试命令3.8 跳出函数&#xff0c;跳入函数3.9、查看当前函数所有参数3.10 打印变量的值3.11、打印变量类型…

11. 盛最多水的容器

给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水量。 说明&#xff1a;你不能倾斜容器。 示例…

【openGauss】在openEuler(ARM架构)上安装openGauss(单机版)

一、系统版本介绍 当前案例中的openGauss安装&#xff0c;底层操作系统为openEuler-20.03-LTS版本&#xff0c;当前openGauss对Python版本兼容性最好的是Python 3.6版本与Python 3.7版本&#xff0c;该实验使用的openEuler版本自带Python 3.7.4&#xff0c;不需要再自行安装 二…

光电探测器怎么选

想要挑选光电探测器&#xff0c;首先应该理解探测器的重要的几个指标。 实际看一个光电探测器吧 输入输出接口三个部分&#xff0c;光纤输入&#xff0c;射频输出&#xff0c;电源供电 数据手册 捡几个难理解的说说&#xff0c;详细推导解释这里不赘述了&#xff0c;难理解的…