【数据结构】串的模式匹配:简单的模式匹配算法,KMP算法

 欢~迎~光~临~^_^

目录

知识树

1、什么是串的模式匹配 

2、简单的模式匹配算法

3、KMP算法

3.1 算法原理

3.2 C语言实现KMP算法 

3.3 求next数组

3.4 KMP算法优化(对next数组的优化) 


知识树

 

1、什么是串的模式匹配 

        串的模式匹配是在一个字符串中查找另一个较小的字符串(称为模式)的过程。模式匹配的目的是在文本串中查找一个或多个匹配字符串。这种搜索可以使用各种算法进行,包括暴力算法,KMP算法和Boyer-Moore算法等。模式匹配广泛应用于文本编辑器、搜索引擎、计算机网络和计算机安全等领域。

2、简单的模式匹配算法

        这个算法的时间复杂度是O(mn),其中m是模式串的长度,n是文本串的长度。在最坏情况下,即文本串中的每个字符都匹配模式串中的每个字符,时间复杂度为O(m(n-m+1)),因此朴素模式匹配算法在处理大型文本串时可能会变得很慢。

#include <stdio.h>
#include <string.h>int naive_search(const char text[], const char pattern[]) {int text_len = strlen(text);int pattern_len = strlen(pattern);for (int i = 0; i <= text_len - pattern_len; i++) {int j;for (j = 0; j < pattern_len; j++) {if (text[i + j] != pattern[j])break;}if (j == pattern_len)return i;}return -1;
}int main() {char text[] = "ABABCABCABABABD";char pattern[] = "ABABD";int pos = naive_search(text, pattern);if (pos >= 0)printf("Pattern found at position %d in the text.", pos);elseprintf("Pattern not found in the text.");return 0;
}

3、KMP算法

3.1 算法原理

        KMP算法是一种字符串匹配算法,它的原理是利用已知的信息尽可能减少匹配次数。KMP算法的核心是一个跳转表格,也称为Next数组或失配函数。

        在匹配的过程中,当发现不匹配的情况时,KMP算法会利用跳转表格中已经计算好的信息,直接跳过部分不需要匹配的字符,从而减少匹配次数。具体来说,KMP算法会根据当前匹配的位置和已知的信息,计算出下一个字符需要匹配的位置,从而避免了不必要的匹配操作。

        KMP算法的时间复杂度为O(m+n),其中m和n分别为模式串和文本串的长度,求next数组时间复杂度O(m);模式匹配过程最坏时间复杂度O(n)。相比于朴素的字符串匹配算法,KMP算法在匹配效率和性能上有了很大的提高。

3.2 C语言实现KMP算法 

        下述代码中,next()函数用于计算模式串的next数组,kmp()函数用于在文本串中查找模式串。在main()函数中,首先输入文本串和模式串,然后调用next()函数生成模式串的next数组,最后调用kmp()函数在文本串中查找模式串。若模式串存在于文本串中,输出模式串在文本串中的位置,否则输出不存在的信息。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>void next(char *pattern, int *next_arr) {int i = 0, j = -1;next_arr[0] = -1;int len = strlen(pattern);while (i < len - 1) {if (j == -1 || pattern[i] == pattern[j]) {i++;j++;next_arr[i] = j;} else {j = next_arr[j];}}
}int kmp(char *text, char *pattern, int *next_arr) {int i = 0, j = 0;int text_len = strlen(text), pattern_len = strlen(pattern);while (i < text_len && j < pattern_len) {if (j == -1 || text[i] == pattern[j]) {i++;j++;} else {j = next_arr[j];}}if (j == pattern_len) {return i - j;} else {return -1;}
}int main() {char text[100], pattern[100];int next_arr[100];printf("请输入文本串:");gets(text);printf("请输入模式串:");gets(pattern);next(pattern, next_arr);int index = kmp(text, pattern, next_arr);if (index != -1) {printf("模式串在文本串中的位置是:%d\n", index);} else {printf("文本串中不存在模式串!\n");}return 0;
}

3.3 求next数组

        next(j)的含义是:在子串的第j个字符与主串发生失配时,则跳到子串的next(j)位置重新与主串当前位置进行比较。
        next(1)都无脑写0;next(2)都无脑写1;
        其他next:在不匹配的位置前,划一根分界线,模式串一步一步往后退,直到分界线之前“能对上”,或模式串完全跨过分界线为止,此时 j 指向哪,next数组值就是多少。

void next(char *pattern, int *next_arr) {int i = 0, j = -1;next_arr[0] = -1;int len = strlen(pattern);while (i < len - 1) {if (j == -1 || pattern[i] == pattern[j]) {i++;j++;next_arr[i] = j;} else {j = next_arr[j];}}
}

        在上述代码中,pattern表示模式串,next_arr表示next数组。首先将next_arr[0]置为-1,i表示当前已匹配的字符数,初始值为0,j表示当前已匹配的字符中,能和下一位字符匹配的最长前缀的末尾位置,初始值为-1。在循环中,若第i个字符能和第j+1个字符匹配,则更新next_arr[i+1]=j+1,否则将j更新为next_arr[j],重复此过程直到结束。

例1,若模式串为ABCDABD,则next数组为[-1, 0, 0, 0, 0, 1, 2, 0]

例2,下面是"ababaaababaa"模式串对应的next数组值:

- a b a b a a a b a b a a
- 0 0 1 2 3 4 5 2 3 4 5 6

因此,"ababaaababaa"模式串的next数组值为[0, 0, 1, 2, 3, 4, 5, 2, 3, 4, 5, 6]。

next数组的生成过程是KMP算法的核心部分,它可以大大提高模式匹配的效率。

3.4 KMP算法优化(对next数组的优化) 

                KMP算法优化:可以采用KMP算法的优化手段,通过推导next[j]和nextval[next[j]]的关系,减少计算次数。

//核心代码
nextval[1]=0;  
for(int j = 2;j < pattern.length;j++)
{if(pattern[next[j]] == pattern[j])nextval[j] = nextval[next[j]];elsenextval[i] = nextval[j];
}

🤞❤️🤞❤️🤞❤️串的模式匹配的知识点总结就到这里啦,如果对博文还满意的话,劳烦各位看官动动“发财的小手”留下您对博文的赞和对博主的关注吧🤞❤️🤞❤️🤞❤️

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

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

相关文章

vscode和HBuilderx设置快捷键注释

一、vscode设置快捷键注释 1.打开vscode&#xff0c;使用快捷键&#xff1a;ctrlshiftp mac的话快捷键是&#xff1a;commandshiftp 然后在行中输入snippets 2.选择“新建”&#xff0c;选择将要配置的文件类型&#xff08;以vue类型为例&#xff09;我这里创建的名字为vue.…

使用docker创建minio镜像并上传文件,提供demo

使用docker创建minio镜像并上传文件&#xff0c;提供demo 1. 整体描述2. 环境搭建2.1 windows环境搭建2.2 docker部署 3. spring集成3.1 添加依赖3.2 配置文件3.3 创建config类3.4 创建minio操作类3.5 创建启动类3.6 测试controller 4. 测试操作4.1 demo运行4.2 页面查看4.3 上…

【云计算】虚拟私有网络 VPC

虚拟私有网络 VPC 1.VPC 简介1.1 VPC 相关基本概念1.2 其他相关基本概念 2.VPC 通信场景2.1 VPC 内部互通2.2 VPC 间互通2.2.1 对等连接2.2.2 Transit Gateway 或者云联网 2.3 访问 Internet2.3.1 Internet 网关2.3.2 NAT 网关 2.4 访问本地网络2.4.1 VPN 连接2.4.2 专线接入2.…

pytorch生成CAM热力图-单张图像

利用ImageNet预训练模型生成CAM热力图-单张图像 一、环境搭建二、主要代码三、结果展示 代码和图片等资源均来源于哔哩哔哩up主&#xff1a;同济子豪兄 讲解视频&#xff1a;CAM可解释性分析-算法讲解 一、环境搭建 1&#xff0c;安装所需的包 pip install numpy pandas mat…

原生微信小程序中进行 API 请求

原生微信小程序中进行 API 请求 当在原生微信小程序中进行 API 请求时&#xff0c;封装请求可以提高代码的可维护性和可扩展性。在本篇博客中&#xff0c;我们将一步步介绍如何进一步封装请求&#xff0c;并添加请求超时、拦截器和请求取消功能。 第一步&#xff1a;基本请求封…

混淆矩阵细致理解

1、什么是混淆矩阵 混淆矩阵&#xff08;Confusion Matrix&#xff09;是深度学习和机器学习领域中的一个重要工具&#xff0c;用于评估分类模型的性能。它提供了一个清晰的视觉方式来展示模型的预测结果与真实标签之间的关系&#xff0c;尤其在分类任务中&#xff0c;帮助我们…

【Unity基础】2.网格材质贴图与资源打包

【Unity基础】2.网格材质贴图与资源打包 大家好&#xff0c;我是Lampard~~ 欢迎来到Unity基础系列博客&#xff0c;所学知识来自B站阿发老师~感谢 &#xff08;一&#xff09;网格材质纹理 第一次接触3D物体的话&#xff0c;会觉得好神奇啊&#xff0c;这个物体究竟是由什么组…

基于安卓Java试题库在线考试系统uniapp 微信小程序

本文首先分析了题库app应用程序的需求&#xff0c;从系统开发环境、系统目标、设计流程、功能设计等几个方面对系统进行了系统设计。开发出本题库app&#xff0c;主要实现了学生、教师、测试卷、试题、考试等。总体设计主要包括系统功能设计、该系统里充分综合应用Mysql数据库、…

Ae 效果:CC Particle Systems II

模拟/CC Particle Systems II Simulation/CC Particle Systems II CC Particle Systems II&#xff08;CC 粒子系统 II&#xff09;可用于生成和模拟各种类型的粒子系统&#xff0c;包括火焰、雨、雪、爆炸、烟雾等等。 与 CC Particle World 效果相比有许多类似的属性。最大的…

前端该了解的网络知识

网络 前端开发需要了解的网络知识 URL URL(uniform resource locator,统一资源定位符)用于定位网络服务. URL是一个固定格式的字符串 它表达了: 从网络中哪台计算机(domain)中的哪个服务(port),获取服务器上资源的路径(path),以及要用什么样的协议通信(schema). 注意: 当…

C# wpf 实现桌面放大镜

文章目录 前言一、如何实现&#xff1f;1、制作无边框窗口2、Viewbox放大3、截屏显示&#xff08;1&#xff09;、截屏&#xff08;2&#xff09;、转BitmapSource&#xff08;3&#xff09;、显示 4、定时截屏 二、完整代码三、效果预览总结 前言 做桌面截屏功能时需要放大镜…

卫星物联网生态建设全面加速,如何抓住机遇?

当前&#xff0c;卫星通信无疑是行业最热门的话题之一。近期发布的华为Mate 60 Pro“向上捅破天”技术再次升级&#xff0c;成为全球首款支持卫星通话的大众智能手机&#xff0c;支持拨打和接听卫星电话&#xff0c;还可自由编辑卫星消息。 据悉&#xff0c;华为手机的卫星通话…

【Unity每日一记】资源加载相关和检测相关

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

【计算机网络】Tcp详解

文章目录 前言Tcp协议段格式TCP的可靠性面向字节流应答机制超时重传流量控制滑动窗口&#xff08;重要&#xff09;拥塞控制延迟应答捎带应答标志位具体标志位三次握手四次挥手粘包问题TCP异常情况listen的第二个参数 前言 前面我们学习了传输层协议Udp&#xff0c;今天我们一…

使用FFmpeg+ubuntu系统转化flac无损音频为mp3

功能需求如上题,我们来具体的操作一下: 1.先在ubuntu上面安装FFmpeg:sudo apt install ffmpeg 2.进入有flac音频文件的目录使用下述命令: ffmpeg -i test.FLAC -c:a libmp3lame -q:a 2 output.mp3 3.如果没有什么意外的话,你就能看到你的文件夹里面已经有转化好的mp3文件了 批…

ubuntu中如何用docker下载华为opengauss数据库(超简单)

ubuntu中如何下载华为opengauss数据库 前言一、安装docker1.方法一&#xff1a;2.方法二 二、拉取openguass镜像三、创建容器四、连接数据库 ,切换到omm用户 &#xff0c;用gsql连接到数据库五.最后用DateGrip远程连接测试(1&#xff09;选择数据源(2&#xff09;查看虚拟机ip地…

#循循渐进学51单片机#定时器与数码管#not.4

1、熟练掌握单片机定时器的原理和应用方法。 1&#xff09;时钟周期&#xff1a;单片机时序中的最小单位&#xff0c;具体计算的方法就是时钟源分之一。 2&#xff09;机器周期&#xff1a;我们的单片机完成一个操作的最短时间。 3)定时器&#xff1a;打开定时器“储存寄存器…

Python提取JSON数据中的键值对并保存为.csv文件

本文介绍基于Python&#xff0c;读取JSON文件数据&#xff0c;并将JSON文件中指定的键值对数据转换为.csv格式文件的方法。 在之前的文章Python提取JSON文件中的指定数据并保存在CSV或Excel表格文件内&#xff08;https://blog.csdn.net/zhebushibiaoshifu/article/details/132…

Windows PostgreSql 创建多个数据库目录

1 使用默认用户Administrator 1.1初始化数据库目录 E:\Program Files\PostgreSQL\13> .\bin\initdb -D G:\DATA\pgsql\data3 -W -A md5 1.2连接数据库 这时User为Administrator&#xff0c;密码就是你刚才设置的&#xff0c;我设置的为123456&#xff0c;方便测试。 2 添加…

黑马JVM总结(九)

&#xff08;1&#xff09;StringTable_调优1 我们知道StringTable底层是一个哈希表&#xff0c;哈希表的性能是跟它的大小相关的&#xff0c;如果哈希表这个桶的个数比较多&#xff0c;元素相对分散&#xff0c;哈希碰撞的几率就会减少&#xff0c;查找的速度较快&#xff0c…