kmp算法(c++)

kmp算法的简单介绍

在这里插入图片描述

从主串中快速找到与要找的串的相同位置
如果使用暴力算法去求解这个问题,时间复杂度为O(i*j) => 很大
在这里插入图片描述
kmp算法则是对这类问题的优化
因整理过于麻烦,,详细的介绍可以参照这篇博客,,花时间看完就明白了,写的很棒!!!
kmp算法详细介绍
下面是自己学习的一些注意的地方,主要是针对于代码模版来讲解。

next[i]的介绍

以i为终点的后缀和从1开始的前缀相等,并且保证后缀的长度最长

ex: next[ i ] = j
在这里插入图片描述

p[ 1 , j] = p[ i - j + 1,i]
//p数组中从1到j这一段与 从i-j+1到i这一段相等 

### KMP算法C++实现 KMP(Knuth-Morris-Pratt)算法是一种高效的字符串匹配算法,用于在一个主串中查找模式串是否存在及其位置。以下是基于引用的内容和专业知识构建的完整C++实现。 #### 主要逻辑描述 KMP的核心在于通过计算部分匹配表(也称为`lps[]`数组),减少不必要的字符比较次数。该数组记录了模式串的部分匹配长度,从而指导跳转操作[^1]。 #### 预处理阶段:构建LPS数组 在实际应用中,首先需要对模式串进行预处理以生成最长前缀后缀数组 `lps[]`: ```cpp void computeLPSArray(const std::string& pattern, int M, int* lps) { int length = 0; // 当前已知的最大公共前后缀长度 lps[0] = 0; // 前缀后缀不重叠的情况 int i = 1; while (i < M) { if (pattern[i] == pattern[length]) { length++; lps[i] = length; i++; } else { // 不相等时回退到更短的前缀 if (length != 0) { length = lps[length - 1]; } else { lps[i] = 0; i++; } } } } ``` 此函数实现了如何动态调整指针来填充`lps[]`数组[^2]。 #### 搜索阶段:执行模式匹配 完成上述准备工作之后,即可利用得到的信息快速定位目标子串的位置: ```cpp std::vector<int> KMPSearch(const std::string& text, const std::string& pattern) { int N = text.length(); int M = pattern.length(); std::vector<int> result; // 存储所有匹配起始索引 int *lps = new int[M]; // 创建 LPS 数组 computeLPSArray(pattern, M, lps); int i = 0; // 文本遍历指针 int j = 0; // 模式串遍历指针 while ((N - i) >= (M - j)) { if (pattern[j] == text[i]) { j++; i++; } if (j == M) { // 完全匹配成功 result.push_back(i - j); j = lps[j - 1]; } else if (i < N && pattern[j] != text[i]) { if (j != 0) j = lps[j - 1]; else i++; } } delete[] lps; // 清理内存资源 return result; } ``` 以上代码展示了完整的KMP搜索过程,并返回所有的匹配起点列表[^3]。 #### 使用示例 下面是一个简单的调用例子展示其功能: ```cpp #include <iostream> #include <vector> #include <string> int main() { std::string text = "ABABCABAB"; std::string pattern = "AB"; std::vector<int> matches = KMPSearch(text, pattern); for(auto pos : matches){ std::cout << "Pattern found at index: " << pos << "\n"; } return 0; } ``` 运行这段程序将会打印出模式串 `"AB"` 出现在原始文本中的每一个位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少年负剑去

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值