KMP算法

KMP

KMP 算法是一个快速查找匹配串的算法,它的作用其实就是本题问题:如何快速在「原字符串」中找到「匹配字符串」。

而 KMP 算法的复杂度为 O(m+n)实际上是O(N),因为O(M)不可能大于O(N)

KMP 之所以能够在 O(m+n)复杂度内完成查找,是因为其能在「非完全匹配」的过程中提取到有效信息进行复用,以减少「重复匹配」的消耗。

KMP解决的问题

KMP解决,如何查 m 是否是 字符串 s 的字串
暴力解法 : 尝试每一个字符串的开头,来模拟是否匹配 , 时间复杂度(M*N)

 public int strStr(String ss, String pp) {int n = ss.length(), m = pp.length();char[] s = ss.toCharArray(), p = pp.toCharArray();// 枚举原串的「发起点」for (int i = 0; i <= n - m; i++) {// 从原串的「发起点」和匹配串的「首位」开始,尝试匹配int a = i, b = 0;while (b < m && s[a] == p[b]) {a++;b++;}// 如果能够完全匹配,返回原串的「发起点」下标if (b == m) return i;}return -1;}

KMP利用了字符串 M 的 每个字符,的最长前缀与后缀匹配的长度信息来加速移动

举例 :
在这里插入图片描述

next数组: 将 i 位置的字符的最长前缀信息存到一个数组 , 这个数组就是next 数组
第一个字符因为:没有字符 所以规定为 -1
第二个字符因为:只有一个字符 所以规定为 0

先不说加速next的过程 ,我们能办到 将所有字符的信息都求出来
在这里插入图片描述

然后现在来讲解,如何根据 next数组来加速 字符串 s 与字符串 m 的匹配过程

如果从第一个字符开始 , 经典过程是, 如果我发现第 i 个字符不相等的时候 ,我 s 字符串 的下标 要跳到第 2 个字符(从第二个字符开始 ) , m 字符串的下标要跳回到 第一个字符重新匹配 ,这就是经典过程
而 KMP 是, 当发现 i 位置开头 ,一路往下比, 直到比到 S字符不与 Y 字符不一致的时候 , 我能根据 next 数组, 的最大长度, Y位置最长前缀的后面 ,而 S 字符位置不变

举例 :

在这里插入图片描述
为什么 Y能回跳? 而X字符不变?
在这里插入图片描述
在这里插入图片描述

好得,接下来我们讲解如何加速 next数组信息的过程
我们知晓: next数组存放的都是最长的前缀匹配长度, 所以当下一个字符想要求 最长前缀长度的时候,我们可以利用next数组的信息, 我们直接跳到,之前的最长前缀长度的下一位来与当前字符进行匹配, 如果匹配成功,我们当前字符的最长前缀长度就是匹配到的前一个的前缀长度加1 , 如果匹配失败, 那我们就继续先前跳,知道跳到不能跳了,写成0

package Str;public class KMP {//求一个字符串是不是另一个字符串的字串
//    整体复杂度O(N) 因为O(M)是不可能超过O(N)的public static int getIndexOf(String s,String m){if (s == null || m == null || m.length() >s.length() || m.length() < 1){return -1;}char[] str1 = s.toCharArray();char[] str2 = m.toCharArray();int i1= 0;int i2 = 0;int[] next = getNextArray(str2);//O(M)while (i1 < str1.length && i2 < str2.length){//i2 == str2.length的时候代表着,肯定匹配到了//O(N)if (str1[i1] == str2[i2]){//当前字符相等, 共同加加i1++;i2++;}else if (next[i2] == -1){//如果没有前缀和后缀匹配的,那没办法,只能往后走了i1++;}else {//如果不等,则找前缀和后缀最大的那个//要验证之前走过的是否有与str2匹配的情况i2 = next[i2];}}return i2 == str2.length ? i1-i2:-1;}public static int[] getNextArray(char[] ms){if (ms.length == 1){return new int[]{-1};}int[] next = new int[ms.length];next[0] = -1;next[1] = 0;int i = 2;int cn = 0;//即代表那个位置的值与i-1的值比while (i < next.length){if (ms[i-1] == ms[cn]){next[i++] = ++cn;}else if (cn > 0){//当前跳到cn位置的字符,和i-1位置的对应不上cn = next[cn];}else {//当cn为-1的时候,代表跳到了0下标的位置了next[i++] = 0;}}return next;}public static void main(String[] args) {String  s = "leetcode";String  m = "leeto";getIndexOf(s,m);}
}

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

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

相关文章

巴斯夫与长三角物理研究中心开展合作,专注固态和钠离子电池领域

“巴斯夫&#xff0c;全球知名化学公司&#xff0c;宣布与长三角物理研究中心合作&#xff0c;在江苏溧阳市成立联合研究中心&#xff0c;专注于固态电池和钠离子电池的科研。” 根据巴斯夫官方微博消息&#xff0c;新成立的研究中心名为“巴斯夫–长三角物理研究中心新能源汽车…

高德地图的使用

JS API 结合 Vue 使用 高德地图 jsapi 下载、引入 npm add amap/amap-jsapi-loaderimport AMapLoader from amap/amap-jsapi-loader 使用2.0版本的loader需要在window对象下先配置 securityJsCode JS API 安全密钥使用 JS API 使用 script 标签同步加载增加代理服务器设置…

【计算机网络】网络编程套接字(二)

文章目录 网络编程套接字&#xff08;二&#xff09;简单TCP服务器实现创建套接字服务器绑定服务器监听服务器接收连接服务器处理请求 简单TCP客户端实现创建套接字客户端发起连接客户端发起请求 服务器简单测试服务器简单测评多进程版TCP服务器捕捉SIGCHLD信号孙子进程提供服务…

【RuoYi-Cloud-Plus】学习笔记 09 - Sentinel(四)熔断降级知识整理

文章目录 前言参考目录版本说明学习笔记1、包结构2、DegradeSlot3、DegradeRule4、DegradeRuleManager5、CircuitBreaker5.1 CircuitBreaker.State6、AbstractCircuitBreaker6.1、AbstractCircuitBreaker#fromCloseToOpen6.2、AbstractCircuitBreaker#fromHalfOpenToOpen6.3、A…

支付宝接入

支付宝接入 python-alipay-sdk pycryptodome一、电脑网站支付 1.1 获取支付宝密钥 沙箱网址 1.APPID 2.应用私钥 3.支付宝公钥1.2 存放密钥 在与 settings.py 的同级目录下创建 pem 文件夹pem 文件夹下创建 app_private_key.pem 和 alipay_public_key.pem app_private_key…

神经网络初谈

文章目录 简介神经网络的发展历程神经网络的初生神经网络的第一次折戟神经网络的新生&#xff0c;Hinton携BP算法登上历史舞台命途多舛&#xff0c;神经网络的第二次寒冬神经网络的重生&#xff0c;黄袍加身&#xff0c;一步封神神经网络的未来&#xff0c;众说纷纭其他时间点 …

STM32 Proteus仿真LCD12864俄罗斯方块-FZ0063

STM32 Proteus仿真LCD12864俄罗斯方块-FZ0063 Proteus仿真小实验&#xff1a; STM32 Proteus仿真LCD12864俄罗斯方块-FZ0063 功能&#xff1a; 硬件组成&#xff1a;STM32F103R6单片机 LCD12864显示器多个按键 1.标准俄罗斯方块经典游戏玩法&#xff0c;带计时&#xff0c…

Kong 服务和路由的添加

管理服务 这里参考DB-less-Mode&#xff0c;因为使用的是yaml配置文件的形式&#xff0c;所以所有的相关配置只需要往初始化的kong.yml文件中添加就可以了&#xff0c;就像nginx的配置文件 DB-less-Mode 创建服务 vim /etc/kong/kong.yml services: - name: my-service #…

MySQL---表数据高效率查询(简述)

目录 前言 一、聚合查询 &#x1f496;聚合函数 &#x1f496;GROUP BY子句 &#x1f496;HAVING 二、联合查询 &#x1f496;内连接 &#x1f496;外连接 &#x1f496;自连接 &#x1f496;子查询 &#x1f496;合并查询 &#x1f381;博主介绍&#xff1a;博客名…

Idea 修改默认 Maven 为自己的

每次我们打开新项目时,都要去配置一遍 maven,很麻烦,其实可以去修改 idea 里面默认的 maven 配置,这样后面不管是打开新项目还是老项目,就都是用的自己的 maven 了. 1.文件->新项目设置->新项目的设置 File->Other Settings -> Settings for New Project 2.然后和…

git下载源码及环境搭建之数据库(二)

学习目标&#xff1a; 数据库 新项目使用 数据库文件 的配置 及相关属性的设置 步骤&#xff1a; 数据库 下图所示为开发时所用数据库 第一步&#xff1a;新建一个数据库 注意&#xff1a; 字符集与排序规则我们应该选择utf-8 相关 选中新创建的表&#xff0c;点击备份—还…

MySQL单表查询练习题

目录 第一题 第二题 第三题 第一题 1.创建数据表pet&#xff0c;并对表进行插入、更新与删除操作&#xff0c;pet表结构如表8.3所示。 (1&#xff09;首先创建数据表pet&#xff0c;使用不同的方法将表8.4中的记录插入到pet表中。 mysql> create table pet( name varchar(…

centos7.9php8swoole5swoft2环境安装遇到确实redis扩展的解决办法

1、环境介绍 运行系统&#xff1a;centos7.9 php版本&#xff1a;php8.0.29 swoole版本&#xff1a;swoole5 swoft版本&#xff1a;swoft2.02、遇到的问题 The requested PHP extension ext-redis * is missing from your system. Install or enable PHPs redis extension。这…

python爬虫哪个库用的最多

目录 常用的python爬虫库有哪些 1. Requests&#xff1a; 2. BeautifulSoup&#xff1a; 3. Scrapy&#xff1a; 4. Selenium&#xff1a; 5. Scrapy-Redis&#xff1a; 哪个爬虫库用的最多 Scrapy示例代码 总结 常用的python爬虫库有哪些 Python拥有许多常用的爬虫库…

Java反射与“整活--(IOC容器)”

文章目录 前言反射什么是反射基本操作获取类对象获取类属性获取类方法方法的执行对构造方法的操作 注解定义获取注解 整活&#xff08;IOC容器&#xff09;项目结构IOC/DI流程ApplicationContextBeanDefinitionReaderBeanDefinitionBeanWrappergetBean&#xff08;&#xff09;…

Django_admin数据管理后台

目录 一、基础操作 二、自定义后台操作数据行为 源码等资料获取方法 admin数据管理后台是django内置的一个后台管理界面&#xff0c;能查看已注册模型类的数据结构&#xff0c;以及对数据的增删改。 一、基础操作 1.1 检查项目目录下的urls.py有没有如下配置 1.2 创建djan…

技术讨论:我心中TOP1的编程语言

欢迎关注博主 六月暴雪飞梨花 或加入【六月暴雪飞梨花】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术…

Flutter——最详细(NavigationBar)使用教程

NavigationBar简介 Material 3 导航栏组件! 导航栏提供了一种持久且便捷的方式来在应用程序的主要目的地之间进行切换。 使用场景&#xff1a; 底部菜单栏模块 属性作用onDestinationSelected选择索引回调监听器selectedIndex目前选定目的地的索引destinations存放菜单按钮back…

七大排序算法——冒泡排序,通俗易懂的思路讲解与图解(完整Java代码)

文章目录 一、排序的概念排序的概念排序的稳定性七大排序算法 二、冒泡排序核心思想代码实现 三、性能分析四、七大排序算法 一、排序的概念 排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或…

C++之工厂模式

目录 一、为什么要使用工厂模式 优点 缺点 二、简单工厂&#xff08;Simple Factory&#xff09; 好处&#xff1a; 不足&#xff1a; 三、工厂方法&#xff1a; 好处&#xff1a; 不足&#xff1a; 四、抽象工厂&#xff08;Abstract Factory&#xff09; 一、为什…