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

[代码随想录] KMP 算法 28. 找出字符串中第一个匹配项的下标 459. 重复的子字符串

KMP目录

  • KMP 基础知识
    • 构建前缀表
    • 使用前缀表减少运算步骤
  • 28. 找出字符串中第一个匹配项的下标
  • 459. 重复的子字符串

KMP 基础知识

奇乐编程学院
https://www.bilibili.com/video/BV1AY4y157yL/?spm_id_from=333.1391.0.0
代码随想录
https://www.bilibili.com/video/BV1PD4y1o7nd?spm_id_from=333.788.videopod.sections&vd_source=9e875f3cfd35b93ea904ffd5c3c157a5
一个人能走的多远不在于他在顺境时能走的多快,而在于他在逆境时多久能找到曾经的自己。
————KMP

(复制的B站评论)

概述:使用前缀表来代替重复比较。
kmp算法关键在于:在当前对文本串和模式串检索的过程中,若出现了不匹配,如何充分利用已经匹配的部分。
主要步骤:

  1. 构建前缀表
  2. 遍历字符串,利用前缀表进行更新

构建前缀表

前缀不包含尾字母,一定包含首字母的所有子串。
后缀不包含首字母,一定包含尾字母的所有字串。
在构建前缀表的时候就使用了KMP思想。
在这里插入图片描述
在这里插入图片描述

使用前缀表减少运算步骤

前面i,j都是在同一个字符串下。求重复子串的时候,
KMP算法遇到不匹配的地方,可以直接跳到上一次匹配的地方继续匹配。
在这里插入图片描述

在这里插入图片描述

28. 找出字符串中第一个匹配项的下标

就是存在问题的基础上,如果遍历过程中遇到j==needle.size();直接返回return i-needle.size()+1;
下面注释了一个双指针法,两个指针遍历两个字符串,在没接触KMP时候写的。

class Solution {
public:
    void build_next(vector<int>& next, string s){
        next[0] = 0;
        int j = 0;//前缀的末尾
        for(int i = 1; i < s.size(); i ++){ //i后缀的末尾,就是表示这个子串的结束
            while(j>0 && s[i]!=s[j]){
                j = next[j-1];
            }
            if(s[i] == s[j]){
                j++;
            }
            next[i] = j;
        }
    }
    int strStr(string haystack, string needle) {
        if (needle.empty()) return 0;
        vector<int> next(needle.size());
        build_next(next, needle);
        int j = 0;
        for(int i = 0; i < haystack.size(); i++){
            while(j>0 && haystack[i]!=needle[j]){
                j = next[j-1];
            }
            if(haystack[i] == needle[j]){
                j++;
            }
            if(j == needle.size()) return i-needle.size()+1;
        }
        return -1;
    }
};
        // for(int i=0; i < haystack.size(); i++){
        //     int left = 0;
        //     if(needle[left]==haystack[i]){
        //         int right = i+1;
        //         left++;
        //         while(left<needle.size()){
        //             if(needle[left]!=haystack[right]) break;
        //             left++;
        //             right++;
        //         }
        //         if(left == needle.size()) return i;
        //     }
        // }
        // return -1;

459. 重复的子字符串

在这里插入图片描述

在这里插入图片描述

class Solution {
public:
    void build_next(vector<int>& next, string s){
        int j = 0;
        next[0] = 0;//初始化
        for(int i = 1; i < s.size(); i++){
            while(s[i]!=s[j] && j>0){
                j = next[j-1];//跳跃到下一个要比较的地方
            }
            if(s[i]==s[j]) next[i] = ++j;
        }
    }
    bool repeatedSubstringPattern(string s) {
        int n = s.size();
        vector<int> next(n);
        build_next(next, s);
        int len = next[n-1];
        return len > 0 && n % (n - len) == 0;
    }
};

相关文章:

  • 力扣算法ing(42/100)
  • 向量数据库学习笔记(2) —— pgvector 用法 与 最佳实践
  • 如何将 performance_schema 中的 TIMER 字段转换为日期时间
  • 【云服务器】在Linux CentOS 7上快速搭建我的世界 Minecraft 服务器搭建,并实现远程联机,详细教程
  • 基于springboot+vue的农产品电商平台
  • 【软考-架构】10.2、需求分析-获取-定义-验证-管理
  • 基于LAC拨号的L2TP VPN实验
  • stock-pandas,一个易用的talib的替代开源库。
  • Cyber Weekly #49
  • 用LLama factory时报类似Process 2504721 got signal: 1的解决方法
  • 基于javaweb的SpringBoot水果生鲜商城系统设计与实现(源码+文档+部署讲解)
  • 645.错误的集合
  • 扩散模型总结
  • resnet网络迁移到昇腾执行(OM上篇)
  • ERP、MES和CRM三大企业系统的详细介绍及对比分析
  • 生成树和VRRP实验
  • 【keil】单步调试
  • python学习笔记(3)——元组
  • 【云服务器】在Linux CentOS 7上快速搭建我的世界 Minecraft Fabric 服务器搭建,Fabric 模组详细搭建教程
  • 2. client.chat.completions.create 简单使用
  • 演员刘美含二手集市被曝售假,本人道歉
  • 路边“僵尸车”被人以1450元卖了,嫌疑人被刑拘
  • 柳州警方通报临牌车撞倒行人:扣留涉事车辆,行人无生命危险
  • 新剧|反谍大剧《绝密较量》央一开播,张鲁一高圆圆主演
  • 这些被低估的降血压运动,每天几分钟就管用
  • 持续更新丨伊朗内政部长:港口爆炸已致8人死亡750人受伤