leetcode刷题总结——字符串匹配

news2024/12/24 2:22:10

KMP(字符串匹配算法)

主串或目标串:比较长的,我们就是在它里面寻找子串是否存在;

子串或模式串:比较短的。

前缀:字符串A和B,A = B+S,S非空,则B为A的前缀。

后缀:A = S+B,S非空,则B为A的后缀。

PMT:前缀集合和后缀集合的交集中,最长前缀的长度。

部分匹配表:PMT值集合,字符串的所有前缀的PMT值。
在这里插入图片描述

当出现失配的字符时,我们原来的暴力算法需要将目标串逐个后移,这个过程其实就是拿已经匹配部分的前缀去逐个匹配后缀。如果我们能够知道每一个位置i处,S[0:i]中已经和后缀匹配的前缀,那么我们是不是就可以直接将前缀和后缀对齐,进而跳过了中间一些字符,然后直接去比较模式串i+1处的字符呢?答案是肯定的。

KMP.drawio.png

图中绿色块,就是构建next数组过程中,随着遍历的深入,前缀和后缀的匹配情况。

其实,我们换一个方向去思考或许更容易:

例如红色A处失配,那么我们就将目标串往后移动,我们希望移动到模式串的前缀当前已经遍历到的目标串的后缀匹配字符最多的地方。

我们需要一个next数组记录目标串的当前位置失配时,模式串应该转跳的位置。

next数组与模式串对应。并且next[0] = -1,表示第一个字符没有匹配的前后缀,如果在0位置失配,只能将目标串后移一位,去和模式串的第二位进行匹配。

next数组中如果某一个元素值为-1,其实就是表示模式串当前位置没有匹配的前缀,如果在这个位置失配,那么应该直接将目标串的第一位和模式串的下一位比较。

next数组的构造,是通过模式串自己的前缀和后缀匹配进行的。

next[0]=-1;
// 初始化next数组
int i=0,j=-1;//i指向目标串,j指向模式串
while(i<ch.length){
    if(j==-1){
        // j=-1,说明,与i匹配的地方是空,那么也就说明,模式串已经到开头了
        // 但是还是和目标串不匹配
        // abab bab b和a不匹配,我们应该将i后移再和j匹配。
        i+=1;
        j+=1;
    }
    if(ch[i]==ch[j]){
        i+=1;
        j+=1;
        // 当前位置匹配,next[i]的值等于当前位置之前的字符串的PMT
        next[i]=j;
    }
    else{
        // 当前位置不匹配,对模式串进行转跳,
        // next[j]表示如果在当前位置失配,就应该将模式串的索引转跳到next[j]位置,继续匹配
        j=next[j];
    }
}

next[i]数组的值表示匹配串的i位置失配了,那么就应该拿模式串的前缀继续和当前位置匹配,即转跳到next[i]位置,继续判断是否匹配。

public static int KMP(String Str,String Sub,int pos){
    if (Str == null || Sub == null){
        return -1;
    }
    int i = pos, j = 0;
    int[] next = new int[Sub.length()];
    getNext(next,Sub);
    while(i < Str.length() && j < Sub.length()){
        if (j == -1 || Str.charAt(i) == Sub.charAt(j)){
            i++;
            j++;
        }else {
            j = next[j];
        }
    }
    if (j >= Sub.length()){
        return i-j;
    }else {
        return -1;
    }
}
public static void getNext(int[] next,String sub){
    next[0] = -1;
    next[1] = 0;
    int i = 2,k = 0;
    while(i < next.length){
        if (k ==- 1 || sub.charAt(k) == sub.charAt(i-1)){
            next[i] = k+1;
            i++;
            k++;
        }else {
            k = next[k];
        }
    }
}

示例一

459. 重复的子字符串

/**
 * 方法一:枚举法,由于子串至少有两个,因此,我们枚举子串的长度1<=k<=n//2;
 * 方法二:KMP算法,首先先证明一个原理
 * 假设s的子串为c,且为4个,那么s可以表示为     ccccc
 * 如果我们将第一个c移动到末尾,那么应该还可以组成s。
 * 基于这个原理,我们将s复制一份,变成 ss,如果我们删除ss的第一个字符和最后一个字符
 * 如果s存在子串c,那么,ss经过删除前后两个字符后,中间部分一定还存在和s匹配的字符串
 */

示例二

1392. 最长快乐前缀

/**
 * 思路:kmp算法,首先需要得到字符串s的next数组
 * 然后,根据题意可知,快乐前缀是和后缀匹配的。那么我们就需要知道,next数组中最后一个位置的数值pos
 * pos表示,s最后一个数对应的转跳位置,然后,我们需要进一步比较s[pos]是否等于s[-1]:
 *   a. 等于,则找到了最长的快乐前缀;
 *   b. 不等于,pos位置失配,继续转跳pos=next[pos];
 * 直到s[pos]==s[-1]或者pos==-1为止。
 */

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

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

相关文章

C++从入门到精通(第2版) 中文电子版

前言 C&#xff08;c plus plus&#xff09;是一种计算机高级程序设计语言&#xff0c;由C语言扩展升级而产生&#xff0c;最早于1979年由本贾尼斯特劳斯特卢普在AT&T贝尔工作室研发。C既可以进行C语言的过程化程序设计&#xff0c;又可以进行以抽象数据类型为特点的基于对…

四、GD32 MCU 常见外设介绍

系统架构 1.RCU 时钟介绍 众所周知&#xff0c;时钟是MCU能正常运行的基本条件&#xff0c;就好比心跳或脉搏&#xff0c;为所有的工作单元提供时间 基数。时钟控制单元提供了一系列频率的时钟功能&#xff0c;包括多个内部RC振荡器时钟(IRC)、一个外部 高速晶体振荡器时钟(H…

Python os模块的强大功能与应用详解

概要 在Python中,os模块提供了与操作系统进行交互的功能,允许我们执行各种操作系统任务,如文件和目录操作、环境变量访问、进程管理等。os模块是标准库的一部分,无需额外安装。本文将详细介绍os模块的功能,并提供相应的示例代码,帮助全面掌握这一强大工具。 os 模块概述…

支付宝低代码搭建电商小程序,无需编程,可视化操作

大家好&#xff0c;我是小悟 在数字化浪潮的推动下&#xff0c;为了更快速、高效地搭建电商小程序&#xff0c;支付宝低代码平台凭借其独特优势&#xff0c;为商家提供了便捷的解决方案。 支付宝低代码平台犹如一座精心打造的智慧工坊&#xff0c;让电商小程序的搭建变得轻而易…

【 香橙派 AIpro评测】烧系统运行部署LLMS大模型跑开源yolov5物体检测并体验Jupyter Lab AI 应用样例(新手入门)

文章目录 一、引言⭐1.1下载镜像烧系统⭐1.2开发板初始化系统配置远程登陆&#x1f496; 远程ssh&#x1f496;查看ubuntu桌面&#x1f496; 远程向日葵 二、部署LLMS大模型&yolov5物体检测⭐2.1 快速启动LLMS大模型&#x1f496;拉取代码&#x1f496;下载mode数据&#x…

【Outlook】从Outlook新版回归经典版全攻略

引言 在微软宣布计划于2024年底淘汰邮件应用&#xff08;Mail app&#xff09;之后&#xff0c;许多用户发现新版Outlook应用&#xff08;Outlook (new)&#xff09;在他们的Windows 11/10系统上自动启动。如果您更倾向于使用经典版Outlook&#xff08;Outlook (classic)&…

大气热力学(11)——热力学图的应用之二(焚风)

本篇文章源自我在 2021 年暑假自学大气物理相关知识时手写的笔记&#xff0c;现转化为电子版本以作存档。相较于手写笔记&#xff0c;电子版的部分内容有补充和修改。笔记内容大部分为公式的推导过程。 文章目录 11.1 焚风的概念11.2 焚风形成的原理11.3 焚风的示意图 11.1 焚风…

Caido——Burpsuite强有力的竞品工具

0x00 最近发现一个burpsuite的竞品&#xff1a;Caido&#xff0c;尝试使用了一下&#xff0c;发现它的功能还是挺强大的&#xff0c;而且在用户体验上&#xff0c;比Burpsuite要好不少&#xff01;和大家分享一下。 Caido是一款用RUST语言编写的代理工具&#xff0c;目前处于…

nftables(7)集合(SETS)

简介 在nftables中&#xff0c;集合&#xff08;sets&#xff09;是一个非常有用的特性&#xff0c;它允许你以集合的形式管理IP地址、端口号等网络元素&#xff0c;从而简化规则的配置和管理。 nftables提供了两种类型的集合&#xff1a;匿名集合和命名集合。 匿名集合&…

捷配总结的SMT工厂安全防静电规则

SMT工厂须熟记的安全防静电规则&#xff01; 安全对于我们非常重要&#xff0c;特别是我们这种SMT加工厂&#xff0c;通常我们所讲的安全是指人身安全。 但这里我们须树立一个较为全面的安全常识就是在强调人身安全的同时亦必须注意设备、产品的安全。 电气&#xff1a; 怎样预…

【顺序表】算法题 --- 力扣

一、移除元素 移除元素 这个题让我们移除数组nums中值为val的元素&#xff0c;最后返回k&#xff08;不是val的元素个数&#xff09; 这样显然我们就不能再创建一个数组来解决这个问题了&#xff0c;只能另辟蹊径 思路&#xff1a;双指针 这里定义两个指针&#xff08;l1&…

【Python】连接MySQL数据库:详细教程与示例代码

文章目录 1. 安装必要的库2. 建立与MySQL的连接3. 执行SQL查询4. 插入数据5. 更新数据6. 删除数据7. 错误处理8. 小结 在数据驱动的开发中&#xff0c;连接数据库是一个至关重要的技能。Python作为一门强大的编程语言&#xff0c;提供了多种方式连接并操作MySQL数据库。本文将详…

nuitka 打包python程序成windows exe可执行文件

参考&#xff1a; https://www.zhihu.com/question/281858271/answer/2466245521 https://www.zhihu.com/question/281858271 https://zhuanlan.zhihu.com/p/689115995 https://blog.csdn.net/Pan_peter/article/details/136411229 下载&#xff1a; pydantic-2.6.1 pydantic-…

通讯的概念

通讯的概念 文章目录 通讯的概念1.通讯的基本概念2. 串行通讯与并行通讯2. 全双工、半双工及单工通讯3. 同步通讯与异步通讯4. 通讯速率 1.通讯的基本概念 通讯是指在嵌入式系统中实现数据交换的技术手段&#xff0c;它涉及到硬件与硬件、硬件与软件之间的信息传输。基本概念包…

OneForAll工具:安装指南、使用方法及常见问题解决(超全)

引言 在网络安全领域&#xff0c;子域名收集是信息收集过程中非常重要的一步。OneForAll 是一款功能强大的子域名收集工具&#xff0c;能够帮助我们高效地进行子域名收集。本文将详细介绍 OneForAll 的安装和使用方法&#xff0c;并解决在使用过程中可能遇到的问题。 1. OneFo…

手机找回删除的通讯录号码,2个方法,让你不再烦恼

在数字化的浪潮中&#xff0c;我们的手机通讯录如同一张张精心编织的社会网络图谱&#xff0c;每一串数字背后都蕴藏着一段故事或一个重要的联系。然而&#xff0c;生活总会面临小插曲&#xff0c;总有些时候会不慎将通讯录遗失。不用过多担心&#xff0c;本文将会提供一些方法…

Facebook:数字时代的社交瑰宝

在当今数字化飞速发展的时代&#xff0c;社交媒体已经成为人们日常生活中不可或缺的一部分&#xff0c;而Facebook作为其中的领军者&#xff0c;不仅连接了全球数十亿的用户&#xff0c;更深刻地改变了人们的社交方式和生活方式。本文将探讨Facebook如何成为数字时代的社交瑰宝…

Early Convolutions Help Transformers See Better(NeurIPS 2021, Meta)

paper&#xff1a;Early Convolutions Help Transformers See Better 出发点 本文的出发点是解决 ViT 模型在优化性方面的问题。作者假设问题主要出现在 ViT 的早期视觉处理部分&#xff0c;即 "patchify" 过程&#xff0c;这是通过一个大的步幅和大核卷积来实现的…

Linux入门攻坚——28、php、mysql基础

httpdphp&#xff1a;是在httpd中启用模块&#xff0c;不同的工作模式&#xff0c;使用的模块不同 modules httpd&#xff1a;prefork --> libphp5.so httpd&#xff1a;event or worker --> libphp5-zts.so php&#xff1a;引入zend engine后&#xff0c;分为…

算法实验3:贪心算法的应用

实验内容 &#xff08;1&#xff09;活动安排问题 设有n个活动的集合E{1, 2, …, n}&#xff0c;其中每个活动都要求使用同一资源&#xff0c;而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi&#xff0c;且si <f…