KMP入门与算法题实践

news2024/9/24 15:27:10

基础知识

参考视频

下面是两个b站上个人借鉴学习的视频
第一个视频用来快速理解KMP:
【最浅显易懂的 KMP 算法讲解】 https://www.bilibili.com/video/BV1AY4y157yL/?share_source=copy_web&vd_source=d124eda224bf54d0e3ab795c0b89dbb0

第二、三个视频用来理解流程和写代码:
【帮你把KMP算法学个通透!(求next数组代码篇)】 https://www.bilibili.com/video/BV1M5411j7Xx/?share_source=copy_web&vd_source=d124eda224bf54d0e3ab795c0b89dbb0

文字流程

KMP(Knuth-Morris-Pratt)算法是一种用于字符串匹配的高效算法。它利用之前部分匹配的结果来避免重复的匹配操作,从而提高匹配效率。
KMP算法主要包括两个部分:

  1. 构建部分匹配表(又称前缀函数):该表用于记录每个位置之前的最长相等前后缀的长度。
  2. 字符串匹配过程:利用部分匹配表来加速匹配过程。

算法流程:

  1. 初始化: i 后缀末尾从 1 开始,pre 前缀末尾从 0 开始
  2. 更新 next:i 一直往前,pre 一直回退
    a. 前后缀不相等:连续回退,pre 跳到 next[pre-1] 所指的位置(pre 指针所停留的地方一定是最新的公共前后缀结尾)
    b. 前后缀相等:pre++,next[pre] = pre
  3. 找子串:i 一直往前,j 一直回退
    a. 从前往后遍历模式串
    b. 相等 j++
    c. 不相等连续回退 j 跳到 next[j-1]
    d. 子串匹配完毕返回 i-length
 public int strStr(String haystack, String needle) {
    if (needle.length() == 0) return 0;
    int[] next = new int[needle.length()];
    getNext(next, needle);

    int j = 0;
    for (int i = 0; i < haystack.length(); i++) {
        while (j > 0 && needle.charAt(j) != haystack.charAt(i)) 
        j = next[j - 1];
        if (needle.charAt(j) == haystack.charAt(i)) 
            j++;
        if (j == needle.length()) 
            return i - needle.length() + 1;
    }
    return -1;

}

private void getNext(int[] next, String s) {
    int j = 0;
    next[0] = 0;
    for (int i = 1; i < s.length(); i++) {
        while (j > 0 && s.charAt(j) != s.charAt(i)) 
        j = next[j - 1];
        if (s.charAt(j) == s.charAt(i)) 
            j++;
        next[i] = j; 
    }
}

算法题

P3375 模板 KMP

洛谷P3375
在这里插入图片描述
模板代码如下:

#include <vector>
#include <string>
#include <iostream>
using namespace std;
vector<int>nextNum;
string s1;
string s2;
void getNext(string& s1){
    int pre = 0;
    nextNum.push_back(0);
    for(int i = 1;i<s1.length();i++){
        while(pre>0&&s1[pre]!=s1[i]){
            pre = nextNum[pre-1];
        }
        if (s1[pre]==s1[i]) {
            pre++;
        }
        nextNum.push_back(pre);
    }
}


int main(){
    cin>>s1>>s2;
    getNext(s2);
    int j = 0;
    vector<int> res;
    for(int i = 0;i<s1.length();i++){
        while(j>0&&s1[i]!=s2[j]){
            j = nextNum[j-1];
        }
        if (s1[i]==s2[j]) {
            j++;
        }
        if (j == s2.length()) {
            int t = i - s2.length() + 2;
            res.push_back(t);
            j = nextNum[j-1];//假装失败
        }
    }
    for(int v : res){
        cout<<v<<endl;
    }
    for(int v : nextNum){
        cout<<v<<" ";
    }
    return 0;
}

P4391无线传输

在这里插入图片描述
思路:答案是 n - next[n-1]
一个字符串的公共前后缀长度范围为 0-n-1,也就是没有相同的和都是同一个字符
在这里插入图片描述
重复循环的字符串,根据上面的连等式,最大的公共前后缀一定至少错开一个周期,不然就都是一个字符(实践也是如此,找不出其他情况)
在这里插入图片描述
最大的公共前后缀一定至少错开一个周期,意味着 len-最后的公共前后缀长度=最短的周期长度(一定是最后的 next[n-1] ,不是最大)

acbca 5-1=4
acbac 5-2=3

#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
vector<int>nextNum;
int n;
string s1;
void getNext(string& s1){
    int pre = 0;
    nextNum.push_back(0);
    for(int i = 1;i<s1.length();i++){
        while(pre>0&&s1[pre]!=s1[i]){
            pre = nextNum[pre-1];
        }
        if (s1[pre]==s1[i]) {
            pre++;
        }
        nextNum.push_back(pre);
    }
}


int main(){
    cin>>n>>s1;
    if(s1.length()<=1){
        cout<<s1.length();
        return 0;
    }
    getNext(s1);
    int len = s1.length();
    cout<<len-nextNum[n-1];
    return 0;
}

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

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

相关文章

vue3学习day01-vue3的优势、新的脚手架工具create-vue、创建vue3项目、vue3的项目文件内容、插件变化

1、vue3的优势 &#xff08;1&#xff09;更易维护&#xff1a;组合式api&#xff0c;更好的TypeScript支持 &#xff08;2&#xff09;更快的速度&#xff1a;重写diff算法&#xff0c;模版编译优化&#xff0c;更高效的组件化 &#xff08;3&#xff09;更小的体积&#x…

MES系统:生产实时监控与智能反馈,驱动制造业智能化升级

MES系统&#xff08;Manufacturing Execution System&#xff0c;制造执行系统&#xff09;通过集成多种技术手段和管理模块&#xff0c;实现了生产过程的实时监控与反馈。以下是实时监控与反馈具体实现的详细分析&#xff1a; 一、实时监控 1. 数据采集 传感器与设备集成&am…

nrm: npm 镜像源管理工具

nrm 是 “npm registry manager” 的缩写&#xff0c;是一个 npm 镜像源管理工具&#xff0c;用于在不同的 npm 镜像源之间快速切换&#xff0c;帮助开发者根据需要选择不同的源来加速包的下载或解决网络问题。 常用命令 详细介绍 以下是 nrm 的一些主要特性和用法&#xff1…

精美UI三方用户中心 新版QRuser用户中心主题 | 魔方财务模板

内容目录 一、详细介绍二、效果展示1.部分代码2.效果图展示 三、学习资料下载 一、详细介绍 新版QRuser用户中心主题 | 魔方财务模板 本主题支持魔方财务3.5.7版本&#xff01;可自由切换魔方财务3.5.7版本与其他版本。 本主题基于官方default开发&#xff0c;主要面向企业&…

Java语言程序设计——篇十一(1)

&#x1f33f;&#x1f33f;&#x1f33f;跟随博主脚步&#xff0c;从这里开始→博主主页&#x1f33f;&#x1f33f;&#x1f33f; 欢迎大家&#xff1a;这里是CSDN&#xff0c;我的学习笔记、总结知识的地方&#xff0c;喜欢的话请三连&#xff0c;有问题可以私信&#x1f33…

【数据结构-前缀哈希同余运算】力扣974. 和可被 K 整除的子数组

给定一个整数数组 nums 和一个整数 k &#xff0c;返回其中元素之和可被 k 整除的非空 子数组 的数目。 子数组 是数组中 连续 的部分。 示例 1&#xff1a; 输入&#xff1a;nums [4,5,0,-2,-3,1], k 5 输出&#xff1a;7 解释&#xff1a; 有 7 个子数组满足其元素之和可…

仿真入门!Hypermesh焊接处理方法

某抗硫球阀为对焊端结构&#xff0c;需要焊接袖管。焊接过程产生的高温会造成热影响区域&#xff0c;尤其接头区域产生变形及残余应力&#xff0c;同时O型密封圈处的温度也是焊接生产比较关心的问题。因此&#xff0c;为弄清袖管焊接过程中温度场规律&#xff0c;给实际焊接生产…

RAID 级别:0、1、5、6、10 和 50 傻傻分不清?那是你没看过这篇

号主&#xff1a;老杨丨11年资深网络工程师&#xff0c;更多网工提升干货&#xff0c;请关注公众号&#xff1a;网络工程师俱乐部 早上好&#xff0c;我的网工朋友。 大家都知道&#xff0c;无论是企业级服务器还是个人计算机&#xff0c;数据的安全性和可用性都是至关重要的。…

通配符HTTPS证书快速申请流程

通配符HTTPS证书是一种特别类型的HTTPS证书&#xff0c;它可以为一个主域名及其下级所有子域名提供安全加密。这对于拥有多个子域名的企业来说非常有用&#xff0c;因为它简化了管理流程&#xff0c;并降低了成本。具体申请流程&#xff1a; 注册账号填写230919注册码即可获得…

【C++】实验十四

题目&#xff1a; 1、编写程序&#xff0c;输入a&#xff0c;b&#xff0c;c&#xff0c;检查a&#xff0c;b&#xff0c;c是否满足以下条件&#xff0c;如不满足&#xff0c;由cerr输出有关错误信息。 2、从键盘输入一批数值。要求保留3位小数&#xff0c;在输出时上下行小数…

成都夏光汝网络科技有限公司抖音小店品质与创新的完美结合

在数字经济蓬勃发展的今天&#xff0c;电商行业以其独特的魅力和无限的可能性&#xff0c;正深刻改变着我们的消费习惯与生活方式。其中&#xff0c;抖音小店作为短视频与电商结合的典范&#xff0c;更是以其独特的优势迅速崛起&#xff0c;成为广大消费者喜爱的购物渠道。成都…

企业版邮箱如何确保全球畅邮

企业版邮箱如何确保全球畅邮呢&#xff1f;一邮箱通过多项国际隐私认证&#xff0c;加密技术保障数据安全。二是全球网络部署确保邮件畅通。三提供灵活价格方案&#xff0c;支持用户定制化和跨平台。四是第三方工具集成&#xff0c;提升效率。 一、Zoho邮箱的安全保障 1.1 高…

【Stable Diffusion】影楼再也赚不到你的钱,让SD帮你“拍摄”艺术写真

前言 点击上方「蓝字」关注我们 你能看出下图是一张经过AI技术处理过的写真吗&#xff1f; 通过原图AI合成&#xff0c;简单几步操作&#xff0c;一个无需摄影无需后期的0成本摄影工作室就诞生了。 今天就来教大家怎么用Stable Diffusion做出这样的写真效果。 操作过程 第一…

IDEA使用Docker打包镜像

IDEA使用Docker打包镜像 Docker服务器 想要使用idea直接打包docker镜像&#xff0c;需要一个docker服务&#xff0c;你可以安装windows版本的docker&#xff0c;或者安装Linux版本的docker到虚拟机中&#xff0c;这个根据个人想法即可。本篇文章使用的是Linux&#xff01; W…

一图搞懂,全流程项目管理实践地图,驱动:市场-研发-售后

如何共同协作驱动 市场研发售后&#xff1f; 软件项目交付需要一段时间和长周期&#xff0c;而由于产品研发团队前与市场部门脱节、后又与售后支撑服务团队脱节的话&#xff0c;整体上会加剧项目管理的成本和内部跨部门协作的难度。 如何高效共同协作驱动 市场运营产品研发售…

C# Solidworks二次开发------设置按键打开模型查询

一、代码 public void Open_File(string FileNmae) {Process.Start("explorer.exe", FileNmae); }Open_File("路径"); 二、内容 这个代码很简单&#xff0c;我使用其主要的作用是设置一个按键&#xff0c;可以快速的查看我们已生成的三维模型&#xff0…

2000-2023年上市公司融资约束指数-KZ指数(含原始数据+计算结果)

2000-2023年上市公司融资约束指数-KZ指数&#xff08;含原始数据计算结果&#xff09; 1、时间&#xff1a;2000-2023年 2、来源&#xff1a;上市公司年报 3、指标&#xff1a;证券代码、证券简称、统计截止日期、是否剔除ST或*ST或PT股、是否剔除上市不满一年、已经退市或被…

js数据类型基础

最近投了几家公司面试&#xff0c;其中有一家公司面试官面试我非常感谢他&#xff0c;感觉他像一位老师的角色对于我回答不上来的问题以及回答错误的问题耐心指导。js基础真的很重要&#xff01;&#xff01;面完之后我觉平常我只是看到了问题的表面&#xff0c;并没有深度的了…

基于SpringBoot的电商购物平台设计与实现-计算机毕设 附源码 06411

基于SpringBoot的电商购物平台设计与实现 摘 要 该电商购物平台基于SpringBoot开发&#xff0c;旨在为用户提供便捷的购物体验。注册功能允许用户通过提供账号、密码、昵称、邮箱等信息注册账户&#xff0c;而已注册用户可以使用用户名和密码登录系统。普通用户可以在首页查看…

钉钉机器人调度

钉钉机器人调度 流程操作钉钉开发者后台配置01 添加机器人获取APPKEY和APPSECRET获取权限开启消息推送 02 接收“问题”搭建接口 03 转发到服务器服务器的管理界面机器人配置界面将代码上传到服务器 04 API调度影刀提取数据配置信息--合法性 05 生成答案06 回传到服务器 流程 操…