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

KMP算法(JS)

KMP算法

什么时KMP算法

KMP算法是一种改进的字符串匹配算法

由D.E.Knuth,J.H.Morris和 V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。

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

所以如何记录已经匹配的文本内容,是KMP的重点,也就是next数组。

next数组

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

要弄懂这些,我们首先要了解一下几点问题:

  • 前缀:包含首位字符但不会包含末位字符的子串;
  • 后缀:包含末位字符但不包含首位字符的子串。
  • next数组的定义:当主串与模式串的某一字符不匹配时,模式串要回退的位置(即在匹配过程中,当一次匹配失败时,下一次的匹配不不用冲模式串的第一位位开始匹配);
  • next[j]:其值 = 第j位字符前面j-1位字符组成的子串的前后重合字符数+1。

规律:

  1. next[j]的值每次最多增加1
  2. 模式串的组后一位字符不影响next数组的结果

求next[j]数组的代码:

/*** @param {string[]} ch* @param {int} length* @param {int[]} next*/
function getNext(needle) {let next = [];let j = 0;next.push(j);for (let i = 1; i < needle.length; ++i) {while (j > 0 && needle[i] !== needle[j])j = next[j - 1];if (needle[i] === needle[j])j++;next.push(j);}return next;
}

例:

	  j:1 2 3 4 5 6 p:a b a b a ?(模式串最后一位对next[j]数组是没有影响的)
next[j]:0 1 1 2 3 4 

这里代码的主要思想是回溯,且next[i]值的意义是第i位字符前的字符串的最长公共前后缀的长度+1。

我们首先初始化next[1]=0,接着在next[1]基础上按顺序向后一一遍历,那么我们要求next[i]的值时,我们即已经知道next[i-1]的值假设它的值是j,那么接意味着在数组中从第1位第i-2位的最长相等前后缀是j-1,也就是说在模式串next[1] ~ next[i-2]的范围中:1 ~ j-1i-j+1 ~ i-2这两段长度为j-1的字符串是完全相等的。这是要分两种情况,即第j位字符和第i-1位字符相等,另一种是不相等:

  1. 这时一旦第j位字符和第i-1位字符又相等的话,那么next[i]的最长公共前后缀就是next[j-1]+1,因为后缀多出来的一位字符和前缀多出来的一位字符相等,这是最长公共前后缀自然要加1。
  2. 但如果此时第j位字符和第i-1位字符不相等,那么此时我们找第j位前的最长公共前后缀即next[j]-1,此时我们可以知道next[0 ~ next[j-1]] = next[next[j-1]-j+1 ~ j] 。也就是说,我们以j为分隔点,先将模式串前后分为两段,前后两段除追后一位不相等外其他完全相等,那么前半部分满足这样的等式,意味着后半部分同样满足着这样的等式,即此时我们得到模式串的前i-1项又四段相等的子串,第一段和第四段相等。即next[0 ~ next[j-1]] = next[next[j]-i+1 ~ i-2]。到了这里是否似曾相识,没错,这里就是回溯第一遍的结果,那么再一次出现两种情况,即第next[j-1]+1项和i-1项时否相等:
    1. 相等的话next[i]的最长公共前后缀,就是刚刚比较的两段子串的长度加1即next[j-1]+1
    2. 若不相等,那么我们就需要再一次寻找相等的子串。此时将找到第next[j-1]位前的最长1公共前后缀。
  3. 依次循环,知道找到相等,或者即将回溯到下标为0时停止递归,此时说明没有公共前后缀,那么赋值为1也就是j+1(因为此时j为0)。

KMP模式匹配算法

var strStr = function (haystack, needle) {if (needle.length === 0)return 0;let next = getNext(needle);let j = 0;for (let i = 0; i < haystack.length; ++i) {while (j > 0 && haystack[i] !== needle[j])j = next[j - 1];if (haystack[i] === needle[j])j++;if (j === needle.length)return (i - needle.length + 1);}return -1;
};

相关文章:

KMP算法(JS)

KMP算法 什么时KMP算法 KMP算法是一种改进的字符串匹配算法 由D.E.Knuth&#xff0c;J.H.Morris和 V.R.Pratt提出的&#xff0c;因此人们称它为克努特—莫里斯—普拉特操作&#xff08;简称KMP算法&#xff09;。 KMP的主要思想是当出现字符串不匹配时&#xff0c;可以知道…...

恢复NuGet包_解决:System.BadImageFormatException:无法加载文件或程序集

C#工程 主要是开发了一个 web api接口&#xff0c;这个工程源码去年还可以的&#xff0c;今年换了一个电脑打开工程就报错。 错误提示如下&#xff1a; 在 Microsoft.CodeAnalysis.CSharp.CommandLine.Program.Main(String[] args) Test1 System.BadImageFormatEx…...

Django学习笔记(2)

创建app 属于自动执行了python manage.py 直接在里面运行startapp app01就可以创建app01的项目了 之后在setting.py中注册app01 INSTALLED_APPS ["django.contrib.admin","django.contrib.auth","django.contrib.contenttypes","django.c…...

高德地图开发者平台Python应用实践:快速入门周边商业环境信息查询

高德地图开发平台提供了丰富的API接口&#xff0c;可以方便地进行地图数据的开发和分析。在商业分析数据采集中&#xff0c;使用高德地图开发平台的周边查询功能可以快速获取周边商圈、小区等信息&#xff0c;为商业决策提供数据支持。 针对您的需求&#xff0c;我建议采用以下…...

【ES6】—let 声明方式

一、不属于顶层对象window let 关键字声明的变量&#xff0c;不会挂载到window的属性 var a 5 console.log(a) console.log(window.a) // 5 // 5 // 变量a 被挂载到window属性上了 &#xff0c; a window.alet b 6 console.log(b) console.log(window.b) // 6 // undefin…...

【数据分析入门】Jupyter Notebook

目录 一、保存/加载二、适用多种编程语言三、编写代码与文本3.1 编辑单元格3.2 插入单元格3.3 运行单元格3.4 查看单元格 四、Widgets五、帮助 Jupyter Notebook是基于网页的用于交互计算的应用程序。其可被应用于全过程计算&#xff1a;开发、文档编写、运行代码和展示结果。 …...

反射知识总结

1、反射概述 反射是指对于任何一个Class类&#xff0c;在"运行的时候"都可以直接得到这个类全部成分。在运行时&#xff0c;可以直接得到这个类的构造器对象&#xff1a;Constructor在运行时。可以直接得到这个类的成员变量对象&#xff1a;Field在运行时&#xff0c…...

MongoDB 安装 linux

本文介绍一下MongoDB的安装教程。 系统环境&#xff1a;CentOS7.4 可以用 cat /etc/redhat-release 查看本机的系统版本号 一、MongoDB版本选择 当前最新的版本为7.0&#xff0c;但是由于7.0版本安装需要升级glibc2.25以上,所以这里我暂时不安装该版本。我们选择的是6.0.9版本…...

什么是KNN( K近邻算法)

什么是KNN( K近邻算法) 虽然名字中有NN&#xff0c;KNN并不是哪种神经网络&#xff0c;它全名K-Nearest-Neighbors&#xff1a;K近邻算法&#xff0c;是机器学习中常用的分类算法。 物以类聚&#xff0c;人以群分。KNN的基础思想很简单&#xff0c;要判断一个新数据的类别&…...

Linux查看命令总结

1.动态实时查找命令 使用以下命令的前提是需要在找到日志位置 tail -f server.log 实时展示日志末尾内容&#xff0c;默认最后10行,相当于增加参数 -n 10 tail -n filename; tail命令扩展 查看日志最后20行内容并实时更新日志 tail -f -n 20 server.log或者 tail -fn 20 ser…...

npm报错 Cannot find module ‘@vuepress\core\node_m

通常是由于缺少依赖包或者依赖包版本不兼容引起的。可以尝试以下步骤来解决这个问题&#xff1a; 确保您的项目的依赖包是最新的&#xff0c;可以运行 npm update 命令来更新依赖包。 如果更新依赖包后仍然有问题&#xff0c;可以尝试删除 node_modules 文件夹&#xff0c;并重…...

mybatis入门环境搭建及CRUD

一、MyBatis介绍 1.1 MyBatis的定义 MyBatis是一个开源的Java持久化框架&#xff0c;它可以帮助开发人员简化数据库访问的过程。它提供了一种将SQL语句与Java代码进行映射的方式&#xff0c;使得开发人员可以通过简单的配置文件来定义SQL语句&#xff0c;而无需编写繁琐的JDB…...

小程序变化历史记录

2023年8月26 小程序机号快速验证组件将需要付费使用 自2023年8月26日起&#xff0c;手机号快速验证组件将需要付费使用。标准单价为&#xff1a;每次组件调用成功&#xff0c;收费0.03元 https://blog.csdn.net/qq_37215621/article/details/131453551 自2023年9月1日起&…...

jstack(Stack Trace for Java)Java堆栈跟踪工具

jstack&#xff08;Stack Trace for Java&#xff09;Java堆栈跟踪工具 jstack&#xff08;Stack Trace for Java&#xff09;命令用于生成虚拟机当前时刻的线程快照&#xff08;一般称为threaddump或者javacore文件&#xff09;。 线程快照就是当前虚拟机内每一条线程正在执…...

linux面试题整理

目录标题 基础篇1.说下企业为什么用linux而不用windows&#xff1f;2.linux学过什么&#xff0c;怎么学习的&#xff1f;3.linux基本命令4.linux查看端口、进程、文件类型、挂载5.使用top命令之后前五行会显示什么内容&#xff1f;6.linux怎么查找一个文件7.vim进去后的各种操作…...

Linux笔记

Linux基础命令 Linux的目录结构 /&#xff0c;根目录是最顶级的目录了Linux只有一个顶级目录&#xff1a;/路径描述的层次关系同样适用/来表示/home/itheima/a.txt&#xff0c;表示根目录下的home文件夹内有itheima文件夹&#xff0c;内有a.txt ls命令 功能&#xff1a;列出…...

Dockerfile制作Web应用系统nginx镜像

目录 1.所需实现的具体内容 2.编写Dockerfile Dockerfile文件内容&#xff1a; 默认网页内容&#xff1a; 3.构建镜像 4.现在我们运行一个容器&#xff0c;查看我们的网页是否可访问 5.现在再将我们的镜像打包并上传到镜像仓库 1.所需实现的具体内容 基于centos基础镜像…...

lama-cleaner:基于SOTA AI 模型Stable Diffusion驱动的图像修复工具

介绍 由 SOTA AI 模型提供支持的图像修复工具。从照片中删除任何不需要的物体、缺陷、人物&#xff0c;或擦除并替换&#xff08;由Stable Diffusion驱动&#xff09;照片上的任何东西。 特征 1.多种SOTA AI模型 擦除模型&#xff1a;LaMa/LDM/ZITS/MAT/FcF/Manga 擦除和替…...

LVS-DR模式以及其中ARP问题

目录 LVS_DR LVS_DR数据包流向分析 LVS-DR中ARP问题 问题一 问题二 解决ARP的两个问题的设置方法 LVS-DR特点 LVS-DR优缺点 优点 缺点 LVS-DR集群构建 1.配置负载调度器 2.部署共享存储 3.配置节点服务器 4.测试 LVS 群集 LVS_DR LVS_DR数据包流向分析 客户端…...

2023-08-15 Untiy进阶 C#知识补充5——C#6主要功能与语法

文章目录 一、概述二、静态导入三、异常筛选器四、nameof 运算符 ​ 注意&#xff1a;在此仅提及 Unity 开发中会用到的一些功能和特性&#xff0c;对于不适合在 Unity 中使用的内容会忽略。 一、概述 ​ C#6 的新增功能和语法主要包含&#xff1a; >运算符&#xff08;C#…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中&#xff0c;我们训练出的神经网络往往非常庞大&#xff08;比如像 ResNet、YOLOv8、Vision Transformer&#xff09;&#xff0c;虽然精度很高&#xff0c;但“太重”了&#xff0c;运行起来很慢&#xff0c;占用内存大&#xff0c;不适合部署到手机、摄…...