【杂乱笔记】Kmp字符串匹配算法

2024-08-20 22:04

本文主要是介绍【杂乱笔记】Kmp字符串匹配算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

KMP 算法逻辑

  1. 构建 next 数组
    • 初始化 next 数组,用于存储每个位置的最长相同前后缀长度。
    • 遍历模式字符串patt
      • 如果当前字符与前缀字符匹配,增加前缀长度,并更新 next 数组。
      • 如果不匹配,使用 next[prefix\_len - 1] 回退到上一个可能的前缀长度,继续比较。
  2. 字符串匹配
    • 初始化两个指针 ij,分别指向文本 text 和模式 pattern 的开头。
    • 遍历文本:
      • 如果 text[i]pattern[j] 匹配,移动 ij
      • 如果 j 达到模式长度,说明匹配成功,记录匹配起始位置。
      • 如果不匹配且 j > 0,使用 next[j - 1] 回退 j,继续比较。
      • 如果 j == 0,仅移动 i
  3. 返回结果
    • 如果找到匹配,返回起始索引。
    • 如果没有匹配,返回 -1。

Next数组计算中,如果遇到当前字符与前缀字符不匹配的情况,那么就需要重新在前面遍历的内容中寻找次长的最长相同前后缀(对应代码为prefix_len = next[prefix_len - 1];),之后再与当前字符进行匹配(下一次while循环中的 if (patt[i] == patt[prefix_len])),如果还是匹配不上,那么就再再去之前的最长相同前后缀再次比较。

eg:

某一patt如下:

PattABCABD
Next000120

在匹配D时,我们当前的最长前后缀为AB,这时候通过代码prefix_len = next[prefix_len - 1];,我们相当于是去第一个AB中重新匹配,结果发现还是不匹配并且Next数组对应为0,所以DNext就为0。

#include <iostream>
#include <vector>
#include <string>using namespace std;vector<int> buildNext(const string& patt) {int m = patt.size();vector<int> next(m, 0);int prefix_len = 0;int i = 1;while (i < m) {if (patt[i] == patt[prefix_len]) {prefix_len++;next[i] = prefix_len;i++;} else {if (prefix_len != 0) {prefix_len = next[prefix_len - 1];} else {next[i] = 0;i++;}}}return next;
}int KMPsearch(const string& text, const string& pattern) {vector<int> next = buildNext(pattern);int i = 0; // text 的索引int j = 0; // pattern 的索引int n = text.size();int m = pattern.size();while (i < n) {if (text[i] == pattern[j]) {i++;j++;}if (j == m) {return i - j; // 匹配成功,返回起始索引} else if (i < n && text[i] != pattern[j]) {if (j != 0) {j = next[j - 1];} else {i++;}}}return -1; // 未找到匹配
}int main() {string text = "ababcabcabababd";string pattern = "ababd";int index = KMPsearch(text, pattern);if (index != -1) {cout << "Pattern found at index: " << index << endl;} else {cout << "Pattern not found" << endl;}return 0;
}

补充:前缀函数

此为字符串匹配的另一算法,通过简单转换即可转换为Kmp算法。

  • pi数组的定义:p[i]表示第i个前缀的最长匹配的真前、后缀的长度。
  • len=pi[len-1];这个解释和上述一样,就是寻找一个类似于回文的字符串。
vecotr<int>pi (str.size(),0);
for(int i=1;i<str.size();i++){int len=pi[i-1];while(len!=0&&str[i]!=str[len]){len=pi[len-1];}if(str[i]==str[len]){p[i]=len+1;}
}

这篇关于【杂乱笔记】Kmp字符串匹配算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

openCV中KNN算法的实现

《openCV中KNN算法的实现》KNN算法是一种简单且常用的分类算法,本文主要介绍了openCV中KNN算法的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录KNN算法流程使用OpenCV实现KNNOpenCV 是一个开源的跨平台计算机视觉库,它提供了各

Python中使用正则表达式精准匹配IP地址的案例

《Python中使用正则表达式精准匹配IP地址的案例》Python的正则表达式(re模块)是完成这个任务的利器,但你知道怎么写才能准确匹配各种合法的IP地址吗,今天我们就来详细探讨这个问题,感兴趣的朋... 目录为什么需要IP正则表达式?IP地址的基本结构基础正则表达式写法精确匹配0-255的数字验证IP地

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

MySQL更新某个字段拼接固定字符串的实现

《MySQL更新某个字段拼接固定字符串的实现》在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下... 目录1. 查看字段当前值2. 更新字段拼接固定字符串3. 验证更新结果mysql更新某个字段拼接固定字符串 -

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

详解nginx 中location和 proxy_pass的匹配规则

《详解nginx中location和proxy_pass的匹配规则》location是Nginx中用来匹配客户端请求URI的指令,决定如何处理特定路径的请求,它定义了请求的路由规则,后续的配置(如... 目录location 的作用语法示例:location /www.chinasem.cntestproxy

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘