代码随想录第十天(28)

news2024/9/25 1:23:03

文章目录

  • 28. 找出字符串中第一个匹配项的下标
    • 看答案
    • KMP
      • next数组(前缀表)
      • 最长公共前后缀
      • 如何计算前缀表
      • 前缀表与next数组
      • 时间复杂度分析

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

莫得思路……好久没做题,都已经忘得差不多了

看答案

其实就是自己写一个String的indexOf函数,它的作用是返回某个字符串在另一个字符串中首次出现的位置。

利用的思想是KMP

KMP

例子:
要在文本串:aabaabaafa 中查找是否出现过一个模式串:aabaaf。

KMP主要应用在字符串匹配上。

KMP的主要思想是当出现字符串不匹配时,可以知道一部分之前已经匹配的文本内容,可以利用这些信息避免从头再去做匹配了。

next数组(前缀表)

next数组就是一个前缀表(prefix table)。

前缀表有什么作用呢?

前缀表是用来回退的,它记录了模式串与主串(文本串)不匹配的时候,模式串应该从哪里开始重新匹配。

那么什么是前缀表:记录下标i之前(包括i)的字符串中,有多大长度的相同前缀后缀。

最长公共前后缀

文章中字符串的前缀是指不包含最后一个字符的所有以第一个字符开头的连续子串。

后缀是指不包含第一个字符的所有以最后一个字符结尾的连续子串。

正确理解什么是前缀什么是后缀很重要!

所以字符串a的最长相等前后缀为0。 字符串aa的最长相等前后缀为1。 字符串aaa的最长相等前后缀为2。 等等…

匹配的过程在下标5的地方遇到不匹配,模式串是指向f:
在这里插入图片描述
然后应该找到了下标2,指向b,继续匹配:如图:
在这里插入图片描述

以下这句话,对于理解为什么使用前缀表可以告诉我们匹配失败之后跳到哪里重新匹配 非常重要!

下标5之前这部分的字符串(也就是字符串aabaa)的最长相等的前缀 和 后缀字符串是 子字符串aa ,因为找到了最长相等的前缀和后缀,匹配失败的位置是后缀子串的后面,那么我们找到与其相同的前缀的后面重新匹配就可以了。

所以前缀表具有告诉我们当前位置匹配失败,跳到之前已经匹配过的地方的能力。

如何计算前缀表

在这里插入图片描述
长度为前1个字符的子串a,最长相同前后缀的长度为0。
在这里插入图片描述
长度为前2个字符的子串aa,最长相同前后缀的长度为1。

长度为前3个字符的子串aab,最长相同前后缀的长度为0。

以此类推: 长度为前4个字符的子串aaba,最长相同前后缀的长度为1。 长度为前5个字符的子串aabaa,最长相同前后缀的长度为2。 长度为前6个字符的子串aabaaf,最长相同前后缀的长度为0。

那么把求得的最长相同前后缀的长度就是对应前缀表的元素,如图:
在这里插入图片描述
找到的不匹配的位置, 那么此时我们要看它的前一个字符的前缀表的数值是多少。

然后移动到,从前一个字符处开始,它对应的前缀表是多少,就向前移多少个位置(不包括前一个元素本身),所以移动到b处

其实这里移动到的位置就是前缀表的元素代表的位置,不用前移多少个元素,比如aabaaf中,f处不匹配,应该移动到它的前一个元素a对应的前缀表元素所指的位置,即字符串下标为2的元素处,即b。

前缀表与next数组

很多KMP算法的时间都是使用next数组来做回退操作,那么next数组与前缀表有什么关系呢?

next数组就可以是前缀表,但是很多实现都是把前缀表统一减一(右移一位,初始位置为-1)之后作为next数组。

其实这并不涉及到KMP的原理,而是具体实现,next数组既可以就是前缀表,也可以是前缀表统一减一(右移一位,初始位置为-1)。

时间复杂度分析

其中n为文本串长度,m为模式串长度,因为在匹配的过程中,根据前缀表不断调整匹配的位置,可以看出匹配的过程是O(n),之前还要单独生成next数组,时间复杂度是O(m)。所以整个KMP算法的时间复杂度是O(n+m)的。

暴力的解法显而易见是O(n × m),所以KMP在字符串匹配中极大地提高了搜索的效率。

class Solution {
    public int strStr(String haystack, String needle) {
        int[] next=new int[needle.length()];
        next[0]=0;
        getNext(next,needle);
        int j=0;
        for(int i=0;i<haystack.length();i++){//这里的i是从0开始,此时的目的是要将
        //长的字符串和短的字符串从0号位置开始比较
            while(j>0&&haystack.charAt(i)!=needle.charAt(j)){
                j=next[j-1];
            }
            if(haystack.charAt(i)==needle.charAt(j)){
                j++;
            }
            if(j==needle.length()){
                return i-needle.length()+1;
            }
        }
        
        return -1;
    }
    //获得next数组
    public void getNext(int[] next,String s){
        int j=0;
        for(int i=1;i<s.length();i++){//因为要得到前后相等的公共字符串,而next的0位置的元素
        //一定是0,所以i取1,也就是从next数组的1号元素开始填充
            while(j>0&&s.charAt(i)!=s.charAt(j)){
                j=next[j-1];//回退到前个元素的next数组处
            }
            if(s.charAt(i)==s.charAt(j)){
                j++;
            }
            next[i]=j;
        }
    }
}

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

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

相关文章

ModelScope 垂类检测系列模型介绍

文章目录ModelScope介绍垂类模型介绍调用方式1 Demo Service2 Notebook3 本地使用* 二次开发总结ModelScope介绍 ModelScope 是阿里达摩院推出的 中文版模型即服务&#xff08;MaaS, Model as a Service&#xff09;共享平台。该平台在2022年的云栖大会上发布&#xff0c;之前…

Windows安装系列:SVN Server服务

一、下载与安装 1、下载VisualSVN-Server-5.1.1-x64.msi 地址&#xff1a;Download | VisualSVN Server 2、找到最新版本SVN 5.1.1&#xff0c;直接双击它&#xff0c;弹出如下安装界面 3、点击Next 4、勾选我接受&#xff0c; 点击"Next" 5、默认选项&#xff0c…

stack、queue和priority_queue

目录 一、栈&#xff08;stack&#xff09; 1.stack的使用 2.容器适配器 3.stack的模拟实现 二、队列&#xff08;queue&#xff09; 1.queue的使用 2.queue的模拟实现 三、双端队列&#xff08;deque&#xff09; 1.vector&#xff0c;list的优缺点 2.认识deque 四…

如何调试段错误?

刚接触指针的时候&#xff0c;经常会遇到段错误。 rootTurbo:linklist# ls link.c link.h main main.c rootTurbo:linklist# ./main 链表初始化成功 Segmentation fault (core dumped) rootTurbo:linklist#所谓段错误&#xff0c;就是访问了不能访问的内存。 比如内存不存在…

1.8 正则表达式

正则表示式是用来匹配与查找字符串的&#xff0c;从网上爬取数据不可避免的会用到正则表达式。 Python 的表达式要先引入 re 模块&#xff0c;正则表达式以 r 引导。Re库主要功能函数函数说明re.search()在一个字符串中搜索匹配正则表达式的第一个位置&#xff0c;返回match对象…

七大设计原则之里氏替换原则应用

目录1 里氏替换原则2 里氏替换原则应用1 里氏替换原则 里氏替换原则&#xff08;Liskov Substitution Principle,LSP&#xff09;是指如果对每一个类型为 T1 的对象 o1,都有类型为 T2 的对象 o2,使得以 T1 定义的所有程序 P 在所有的对象 o1 都替换成 o2 时&#xff0c;程序 P…

基于蜣螂算法改进的LSTM预测算法-附代码

基于蜣螂算法改进的LSTM预测算法 文章目录基于蜣螂算法改进的LSTM预测算法1.数据2.LSTM模型3.基于蜣螂算法优化的LSTM4.测试结果5.Matlab代码摘要&#xff1a;为了提高LSTM数据的预测准确率&#xff0c;对LSTM中的参数利用蜣螂搜索算法进行优化。1.数据 采用正弦信号仿真数据&…

算法训练——剑指offer(Hash集合问题)

摘要 数据结构中有一个用于存储重要的数据结构&#xff0c;它们就是HashMap,HasSet&#xff0c;它典型特征就是存储key:value键值对。在查询制定的key的时候查询效率最高O(1)。Hashmap&#xff0c;HasSet的底层结构是如图所示。它们的区别就是是否存在重复的元素。 二、HashMa…

搞了个ChatGPT机器人,免费使用最强大的AI,这一晚上几个群都聊high了

前言 最近ChatGPT实在是太火了&#xff01;其实去年年底的时候&#xff0c;ChatGPT已经在程序员圈子里小小的火了一把&#xff0c;再加上年后资本的炒作和各个公司疯狂的蹭热点&#xff0c;就彻底火出圈了。 ChatGPT使用体验 其实自己已经用了一段时间的ChatGPT&#xff0c;…

UART和RS232、RS485的联系和区别、以及对软件编程的影响

1、串口、UART、RS232、RS485概念的理解 (1)狭义上的串口&#xff1a;指的是串口协议&#xff0c;就是时序图、数据收发先后顺序等&#xff0c;是抽象出来的协议&#xff1b; (2)广义上的串口&#xff1a;指的是符合串口协议的接口&#xff0c;UART、RS232、RS485在实际工作中都…

Python:每日一题之剪格子(DFS剪枝)

题目描述 如下图所示&#xff0c;3 x 3 的格子中填写了一些整数。 我们沿着图中的红色线剪开&#xff0c;得到两个部分&#xff0c;每个部分的数字和都是 60。 本题的要求就是请你编程判定&#xff1a;对给定的 mn 的格子中的整数&#xff0c;是否可以分割为两个部分&#xf…

【fastjson2.x 记录】那些从1.x升级到2.x踩过的坑

这篇文章主要记录升级到 fastjson2.x 版本后出现的一些问题 1. jar 包引入问题 问题描述&#xff1a;从 2.x 版本后&#xff0c;fastjson 貌似开始对代码模块进行了拆分&#xff0c;所以在调整配置的时候&#xff0c;会发现有些类突然没了&#xff0c;其实是需要引入其他的扩展…

ChatGPT超详细注册教程,只要3.5!

一、注册必备条件注册 ChatGPT 必备如下三个条件&#xff1a;1、用于注册ChatGPT的邮箱&#xff0c;什么邮箱都可以。2、科学上网工具&#xff0c;注册账号和登录时需要。3、一个国外手机号&#xff0c;用于接收验证码&#xff0c;后面会详细介绍如何花 3.55 元获取。二、注册 …

从10大管理看产品经理的日常工作——产品整体管理

产品经理这个职业有其特殊性&#xff0c;在学校&#xff0c;没有专门的专业或课程教授你如何成为一名产品经理&#xff0c;虽然我们给产品经理划分了初级、中级、高级&#xff0c;但是却没有相应的职称可以证明你的级别&#xff0c;也没有相关的职业证书可以证明你的能力。产品…

LVGL V9.0基于VS2022仿真搭建

完整Demo&#xff0c;lvgl,lvgl_drivers相关资料下载 链接&#xff1a;https://pan.baidu.com/s/1DNJeHdoaPyfe1BsLb9wjRg 提取码&#xff1a;wov7 其它资料下载 链接&#xff1a;https://pan.baidu.com/s/1nV9jojPEPWSWZdYhaCZWTA 提取码&#xff1a;91j8 下载资料后解压文…

贝叶斯分类器

分类算法用来判断给定数据项所属的类别&#xff0c;即种类或类型。比如&#xff0c;可以根据某些特征来分辨一部电影属于哪个流派&#xff0c;等等。这样&#xff0c;流派就是我们要预测的类别。第10章“预测性分析与机器学习”还会对机器学习做进一步介绍。此刻&#xff0c;我…

分布式ID生成方案

文章目录前言一、分布式ID需要满足的条件二、分布式ID生成方式基于UUID数据库自增数据库集群数据库号段模式redis ID生成基于雪花算法&#xff08;Snowflake&#xff09;模式百度&#xff08;uid-generator&#xff09;美团&#xff08;Leaf&#xff09;滴滴&#xff08;Tinyid…

queue(二)优先级队列解决 合并K个已排序链表(hard)

合并k个已排序的链表_牛客题霸_牛客网【牛客题霸】收集各企业高频校招笔面试题目&#xff0c;配有官方题解&#xff0c;在线进行百度阿里腾讯网易等互联网名企笔试面试模拟考试练习,和牛人一起讨论经典试题,全面提升你的技术能力https://www.nowcoder.com/practice/65cfde9e5b9…

[MySQL教程②] - MySQL介绍和发展史

目录 ❤ MySQL介绍 ❤ 什么是数据库 ❤ 什么是数据 ❤ 数据库管理系统 ❤ NoSQL特性总览 ❤ NoSQL的分类、特点、典型产品 ❤ 常见的数据库产品有哪些&#xff1f; ❤ Oracle公司产品介绍 Oracle数据库版本介绍 Oracle的市场应用 MySQL数据库版本介绍 MyS…

阅读MySQL必知必会,查缺补漏

MySQL自带数据库 information_schema&#xff1a;是MySQL自带的数据库&#xff0c;主要保持MySQL数据库服务器的系统信息&#xff0c;比如数据库的名称&#xff0c;数据库表的名称&#xff0c;字段名称&#xff0c;存储权限等。 performance_schema&#xff1a;是MySQL系统自…