24考研数据结构-串的模式匹配kmp以及优化

news2024/11/24 8:58:14

目录

  • 4.2串的模式匹配
    • 4.2.1朴素模式匹配算法
        • 时间复杂度分析:
    • 4.2.2改进的模式匹配算法——KMP算法
      • 1. 求next数组
      • 2. 利用next数组进行模式匹配
      • 3. 时间复杂度分析
    • 4.2.3 next数组的优化思路nextval,优化KMP
  • 概括
    • 数据结构:串模式匹配与KMP算法及其优化
      • 串模式匹配
      • KMP算法
        • KMP算法的过程
        • KMP算法的优势
      • KMP算法的优化
      • 结论

4.2串的模式匹配

模式匹配:子串的定位操作称为串的模式,它求的是子串(常称模式串)在主串中的位置。
在这里插入图片描述

4.2.1朴素模式匹配算法

n-m+1主串中能有的串个数

int Index(SString S, SString T){
    int i=1;                //扫描主串S
    int j=1;                //扫描模式串T
    while(i<=S.length && j<=T.length){
        if(S.ch[i] == T.ch[j]){
            ++i;
            ++j;             //继续比较后继字符
        }
        else{
            i = i-j+2;  //回到这次匹配的第一个位置之前+1得到匹配的第一个位置
            //再+1才能得到下一次匹配的第一个位置
            j=1;             //指针后退重新开始匹配
        }
    }
    if(j>T.length)  //匹配成功,返回第一个字符位置
        return i-T.length;
    else
        return 0;
}

时间复杂度分析:

主串长度为n,模式串长度为m
最多比较n-m+1个子串

  • 最坏时间复杂度 = O(nm)
    每个子串都要对比m个字符(对比到最后一个字符才匹配不上),共要对比n-m+1个子串,复杂度 = O((n-m+1)m) = O(nm - m^2 + m) = O(nm)
    PS:大多数时候,n>>m
  • 比较好时间复杂度 = O(n)
    每个子串的第一个字符就匹配失败,共要对比n-m+1个子串,复杂度 = O(n-m+1) = O(n)
    匹配一次就匹配成功:O(m)

4.2.2改进的模式匹配算法——KMP算法

不匹配的字符之前,一定是和模式串一致的;
根据模式串T,求出next数组(只与模式串有关,与主串无关),利用next数组进行匹配,当匹配失败时,主串的指针 i 不再回溯!
next数组是根据子串求出来的,当前面的字符串已知时如果有重复的,从当前的字符匹配即可。

1. 求next数组

  • 作用:当模式串的第j个字符失配时,从模式串的第next[j]继续往后匹配;
  • 对于任何模式串,当第1个字符不匹配时,只能匹配下一个子串,因此,next[1] = 0——表示模式串应右移一位,主串当前指针后移一位,再和模式串的第一字符进行比较;
  • 对于任何模式串,当第2个字符不匹配时,应尝试匹配模式串的第一个字符,因此,next[2] = 1;

在这里插入图片描述
分界线后的第一个元素的位序就是next[j]的值

2. 利用next数组进行模式匹配

int Index_KMP(SString S, SString T, int next[]){
    int i=1;     //主串
    int j=1;     //模式串
    while(i<S.length && j<=T.length){
        if(j==0 || S.ch[i]==T.ch[j]){      //第一个元素匹配失败时
            ++j;
            ++i;         //继续比较后继字符
        }
        else
            j=next[j]   //模式串向右移动
    }
    if(j>T.length)
        return i-T.length; //匹配成功
}


在这里插入图片描述

3. 时间复杂度分析

  • 求next数组时间复杂度 = O(m)
  • 模式匹配过程最坏时间复杂度 = O(n)
  • KMP算法的最坏时间复杂度 = O(m+n)

4.2.3 next数组的优化思路nextval,优化KMP

在这里插入图片描述
如果next[j]的值对应的模式串的值相等,则说明就算跳转到这个位置也一样匹配失败,所以nextval[j]的值就是next[j]的值减一,再判断还会不会一样。

在这里插入图片描述

概括

数据结构:串模式匹配与KMP算法及其优化

在计算机科学中,字符串匹配是一种常见的操作,即在一个文本串中查找一个模式串是否存在,并返回其位置或匹配的结果。串模式匹配涉及到多种算法,其中KMP算法是一种经典且高效的字符串匹配算法。本文将对串模式匹配及KMP算法进行介绍,并讨论其优化方法。

串模式匹配

串模式匹配是指在一个文本串(主串)中查找一个给定的模式串是否存在的问题。在实际应用中,字符串匹配是一个非常常见的操作,例如在文本编辑器中查找关键词、在搜索引擎中搜索相关内容等。在字符串匹配中,最简单的方法是暴力匹配,即从文本串的每个位置开始,逐个字符与模式串进行比较。但暴力匹配算法的时间复杂度较高,特别是在文本串和模式串较长的情况下。

KMP算法

KMP算法是一种高效的字符串匹配算法,它利用模式串自身的特性,在匹配过程中跳过一些无需比较的字符,从而减少比较的次数,提高匹配效率。KMP算法的核心是利用部分匹配表(Partial Match Table,简称PMT)来记录模式串的前缀和后缀的最长公共子串长度,从而决定在匹配过程中模式串的移动位置。

KMP算法的过程

  1. 构建部分匹配表(PMT):首先计算模式串的每个前缀的最长公共前后缀的长度,得到部分匹配表PMT。
  2. 匹配过程:从文本串的第一个字符开始,与模式串的第一个字符进行比较。
  3. 匹配失败:如果比较的字符不相等,则利用PMT中记录的信息来确定模式串的移动位置,跳过一部分无需比较的字符。
  4. 匹配成功:如果比较的字符相等,则继续比较下一个字符,直到模式串全部匹配成功或者文本串结束。

KMP算法的优势

相较于暴力匹配算法,KMP算法具有以下优势:

  • 减少比较次数:KMP算法利用部分匹配表,避免了一些无需比较的字符,减少了比较次数,提高了匹配效率。
  • 避免回溯:KMP算法在匹配失败时,不需要回溯到文本串的前一个位置,而是根据PMT中的信息,直接移动模式串,避免了重复比较。

KMP算法的优化

虽然KMP算法已经是一个高效的字符串匹配算法,但在某些特殊情况下,仍然可以进行进一步的优化。以下是一些KMP算法的优化方法:

  1. 优化部分匹配表(PMT)的构建: 在构建PMT时,可以利用模式串自身的特性,避免重复计算最长公共前后缀的长度,从而减少构建PMT的时间复杂度。

  2. 改进KMP算法的移动方式: 在匹配失败时,KMP算法利用PMT来决定模式串的移动位置,可以考虑优化移动方式,使得匹配过程更加高效。

  3. 应用多模式匹配算法: 如果需要同时匹配多个模式串,可以考虑使用多模式匹配算法,如AC自动机算法,来进一步提高匹配效率。

结论

串模式匹配是计算机科学中一个常见且重要的问题,而KMP算法作为一种高效的字符串匹配算法,在实际应用中具有广泛的用途。通过对KMP算法的优化,可以进一步提高匹配效率,使得字符串匹配操作更加高效和可靠。无论是在文本编辑器、搜索引擎还是其他应用中,串模式匹配与KMP算法的应用都能够为我们带来更好的用户体验和效果。

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

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

相关文章

windows编译新版本linphone

目录​​​​​​​ 环境 获取源码(使用5.0.0版本5.3.0-alpha有问题编译不过) 编译环境准备 编译&#xff08;使用ninja&#xff09; 编译&#xff08;不适用使用ninja&#xff09; 报错解决 linphone-desktop是一款基于SIP的标准开源网络电话系统&#xff0c;它使用了Qt…

下载编译瑞芯微提供的源码1-RK3568

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、下载源码二、编译瑞芯微原厂源码三、电源检查一、下载源码 1.下载 android11 的源码,在网盘资料“iTOP-3568 开发板/iTOP-3568 开发板光 盘资料/20220301(第三版资料)/04_Android11 源码”目…

Python(五十三)列表元素的添加操作

❤️ 专栏简介&#xff1a;本专栏记录了我个人从零开始学习Python编程的过程。在这个专栏中&#xff0c;我将分享我在学习Python的过程中的学习笔记、学习路线以及各个知识点。 ☀️ 专栏适用人群 &#xff1a;本专栏适用于希望学习Python编程的初学者和有一定编程基础的人。无…

leetcode:1757. 可回收且低脂的产品

难度&#xff1a;简单 表&#xff1a;Products ---------------------- | Column Name | Type | ---------------------- | product_id | int | | low_fats | enum | | recyclable | enum | ---------------------- 在 SQL 中&#xff0c;product_id 是这个表…

Spring框架 —— AOP面向切面编程

前言 前面荔枝已经梳理了Spring框架中的IOC部分的知识&#xff0c;接下来荔枝继续梳理Spring框架的另一大重点&#xff1a;AOP面向切面编程。在这篇文章中&#xff0c;荔枝会着重弄清楚AOP的概念并对实现AOP的两种方式进行梳理&#xff0c;同时荔枝也会相应给出代码样例。毕竟荔…

Java面向对象的三大特征

Java面向对象的三大特征 java面向对象的三大特征&#xff1a;“封装、继承、多态”。更多Java技术知识&#xff0c;请登陆疯狂软件教育官网。微信搜索微信号&#xff1a;疯狂软件&#xff0c;参加2015年优惠活动&#xff0c;有机会获得优惠劵和代金劵。 以本文为例&#xff0c…

【腾讯云 Cloud studio 实战训练营】搭建Next框架博客——抛开电脑性能在云端编程(沉浸式体验)

文章目录 ⭐前言⭐进入cloud studio工作区指引&#x1f496; 注册coding账号&#x1f496; 选择cloud studio&#x1f496; cloud studio选择next.js&#x1f496; 安装react的ui框架&#xff08;tDesign&#xff09;&#x1f496; 安装axios&#x1f496; 代理请求跨域&#x…

价格管控有哪些有效的方法

品牌在面对线上店铺的低价、窜货时&#xff0c;需要及时进行干预治理&#xff0c;否则低价效应会蔓延&#xff0c;会有越来越多的店铺跟价&#xff0c;导致渠道更加混乱&#xff0c;但是管控价格也非一时之事&#xff0c;需要品牌按流程治理。 力维网络有多年价格管控经验&…

OpenLayers入门,OpenLayers如何加载TMS瓦片服务,以腾讯地图TMS图层为例

专栏目录: OpenLayers入门教程汇总目录 前言 本章讲解OpenLayers如何加载TMS图层服务到地图上,TMS图层介绍请参考《Gis开发入门,OpenLayers、Leaflet、Maplibre-gl和Cesiumjs地图引擎介绍以及几种地图服务vms、vmts、TMS和XYZ介绍》,下面介绍一下TMS图层和XYZ图层的区别。…

Halcon GPU算法加速测试

Halcon GPU算法加速测试 基本流程 官方加速程序&#xff1a;compute_devices.hdev 1.获取显示本机显卡信息 2.打开、激活设备、准备测试数据 3.GPU 循环测试执行 (affine_trans_image) 4.GPU 循环测试执行(affine_trans_image) 数据传入传出 5.CPU 循环测试执行(affine_…

mysql主从配置及搭建(gtid方式)

一、搭建主从-gtid方式 搭建步骤查看第一篇。bin-log方式。可以进行搭建1.1 gtid和二进制的优缺点 使用 GTID 的主从复制优点&#xff1a; 1、简化配置&#xff1a;使用 GTID 可以简化主从配置&#xff0c;不需要手动配置每个服务器的二进制日志文件和位置。 2、自动故障转移…

【Docker】Docker中安装MySQL数据库

文章目录 1. 前言2. Docker中安装MySQL服务2.1. 查看可用的MySQL版本2.2. 拉取MySQL镜像2.3. 查看本地镜像2.4. 运行容器2.5. 查看正在运行的容器2.6. 查看容器内部2.7. 授权root远程登录2.8. 在宿主机连接到容器的MySQL2.9. 用Navicat连接容器的MySQL 3. 如果是MySQL8.0可能需…

vue项目开发常用工具类

防止重复造轮子&#xff0c;将经常用的函数进行记录&#xff0c;也参考网上的并一起进行记录&#xff0c;后续会持续更新常用到的函数工具类方法&#x1f609;&#x1f609; /** 验证手机号是否合格* true--说明合格*/ export function isPhone(phoneStr) {let myreg /^[1][3,…

VMware vCenter Server Appliance VCSA 备份还原

vCenter是VMware管理员的常备工具&#xff0c;要保护它的安全&#xff0c;我们可以借助vCenter备份还原方式来达成目的。 怎么备份vCenter 7.0&#xff1f; vCenter备份包括vCenter Server核心配置、资源清册和历史数据&#xff0c;如统计信息、事件和任务。接下来&#xff0…

【LeetCode每日一题】——1572.矩阵对角线元素的和

文章目录 一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【题目提示】七【解题思路】八【时间频度】九【代码实现】十【提交结果】 一【题目类别】 矩阵 二【题目难度】 简单 三【题目编号】 1572.矩阵对角线元素的和 四【题目描述】 给你一…

HTTP之Session、Cookie 与 Application

目录 简介cookiecookie生命周期 sessionsession生命周期 HTTP cookies示例application 简介 cookie、seesion、application三个都会缓存我们用户状态的数据&#xff0c;使得我们在浏览器访问网站时可以更快速的获取到信息。 主要原因在于HTTP协议是无状态的&#xff0c;我们每…

IO流(4)- 序列化流与反序列化流

目录 1. 序列化流与反序列化流的基本介绍 2. 序列化流的基本用法&#xff1f; 3. 序列化流的作用&#xff1f; 4. 反序列化流的基本用法&#xff1f; 5. 反序列化流的作用 6. 序列化流与反序列化流使用时需要注意的细节&#xff08;非常重要&#xff09; 6.1 被序列化的…

90%的测试工程师是这样使用Postman做接口测试的

一&#xff1a;接口测试前准备 接口测试是基于协议的功能黑盒测试&#xff0c;在进行接口测试之前&#xff0c;我们要了解接口的信息&#xff0c;然后才知道怎么来测试一个接口&#xff0c;如何完整的校验接口的响应值。 那么问题来了&#xff0c;那接口信息从哪里获取呢&…

中国AI大模型峰会“封神之作”!开发者不容错过这场夏季盛会

年度最强大模型顶会来袭&#xff01;喊话中国数百万AI开发者&#xff0c;速来&#xff01; 硬核来袭&#xff01;中国AI大模型峰会“封神之作”&#xff0c;开发者们不容错过! 前瞻大模型发展趋势&#xff0c;紧跟这场大会&#xff01; 中国科技超级碗&#xff0c;大模型最新前…

SpringCloud Alibaba分布式集群要点

1、可通过nginxkeepalived实现nginx高可用集群。 2、nacos集群&#xff0c;在nacos/conf/cluster.conf配置IP:8848,nginx中配置nacos负载均衡&#xff0c;yml文件使用其对应域名即可。 注&#xff1a;服务器之间内网不通 举例&#xff1a;腾讯服务器之间就存在内网不通的现象…