新闻中心

C++怎么实现一个KMP字符串匹配算法_C++算法设计与KMP原理

2025-11-25
浏览次数:
返回列表
KMP算法通过构建next数组实现高效字符串匹配,利用模式串自身重复信息减少主串指针回退,在O(n+m)时间内完成匹配。核心是预处理生成部分匹配表(next数组),记录各位置最长相等前后缀长度;匹配时失配则根据next数组移动模式串指针,避免主串指针回溯。C++实现包含buildNext和kmpSearch函数,分别构造next数组并执行搜索,适用于长文本场景,较暴力匹配更稳定高效。

c++怎么实现一个kmp字符串匹配算法_c++算法设计与kmp原理

KMP(Knuth-Morris-Pratt)算法是一种高效的字符串匹配算法,能够在O(n + m)时间内找出模式串在主串中的位置,避免了暴力匹配中大量的回溯。C++实现KMP的关键在于预处理模式串生成“部分匹配表”(即next数组),然后利用该表跳过不必要的比较。

理解KMP的核心思想

KMP算法的核心是利用模式串自身的重复信息来减少主串指针的回退。当匹配失败时,主串指针不回退,仅移动模式串指针到合适位置,这个位置由next数组决定。

next数组记录的是:对于模式串每个位置j,其前面子串的最长相等前缀与后缀的长度。例如模式串"ABABC",在位置4(字符'C'前),最长公共前后缀是"AB",长度为2,因此next[4] = 2。

构建next数组(失配函数)

next数组的构造过程也是一个类似KMP匹配的过程,本质上是模式串自己和自己匹配。

  • 初始化next[0] = 0,因为单个字符没有真前后缀
  • 使用两个指针i和j,i遍历模式串,j表示当前最长公共前后缀长度
  • 若pattern[i] == pattern[j],则next[i+1] = j+1,i和j同时后移
  • 若不相等且j > 0,则j回退到next[j-1]继续比较
  • 若j=0,则next[i+1]=0,i继续后移

代码实现:

<font face="Courier New,Courier,monospace">vector<int> buildNext(const string& pattern) {
    int m = pattern.length();
    vector<int> next(m, 0);
    int j = 0;
    for (int i = 1; i < m; i++) {
        while (j > 0 && pattern[i] != pattern[j]) {
            j = next[j - 1];
        }
        if (pattern[i] == pattern[j]) {
            j++;
        }
        next[i] = j;
    }
    return next;
}</font>

执行KMP字符串匹配

使用构建好的next数组进行主串和模式串的匹配。

美图云修 美图云修

商业级AI影像处理工具

美图云修 50 查看详情 美图云修
  • 用i遍历主串,j遍历模式串
  • 字符相等时,i和j都加1
  • 不相等时,若j > 0,则j回退到next[j-1];否则i加1
  • 当j等于模式串长度时,说明找到一次匹配,记录位置并继续

完整匹配函数:

<font face="Courier New,Courier,monospace">vector<int> kmpSearch(const string& text, const string& pattern) {
    vector<int> positions;
    if (pattern.empty()) return positions;
<pre class='brush:php;toolbar:false;'>vector<int> next = buildNext(pattern);
int n = text.length();
int m = pattern.length();
int j = 0;

for (int i = 0; i < n; i++) {
    while (j > 0 && text[i] != pattern[j]) {
        j = next[j - 1];
    }
    if (text[i] == pattern[j]) {
        j++;
    }
    if (j == m) {
        positions.push_back(i - m + 1);
        j = next[j - 1]; // 继续查找下一个匹配
    }
}
return positions;

}

使用示例与注意事项

调用方式简单:

<font face="Courier New,Courier,monospace">int main() {
    string text = "ABABDABACDABABCABC";
    string pattern = "ABABC";
    vector<int> result = kmpSearch(text, pattern);
    for (int pos : result) {
        cout << "Match found at index " << pos << endl;
    }
    return 0;
}</font>

注意边界情况:空模式串、完全匹配、无匹配等。next数组构造是关键,理解j的回退逻辑是掌握KMP的重点。

基本上就这些。KMP虽然初看复杂,但只要搞懂next数组的意义和构造过程,实现起来并不难。在实际应用中,它比暴力匹配稳定高效,尤其适合长文本搜索场景。

以上就是C++怎么实现一个KMP字符串匹配算法_C++算法设计与KMP原理的详细内容,更多请关注其它相关文章!


# 退到  # 怎么做seo销售  # 古风类游戏营销推广  # 沙田网站优化公司  # 塑造品牌网站建设  # 郑州seo优化排名课程  # 临沂公司网站建设哪家好  # 巴中网站建设题库答案  # 邯郸京东网站推广选择  # seo和rank  # 商丘网站推广价格  # 的是  # c++  # 配置文件  # 解决方法  # 怎么做  # 重写  # 时间内  # 有什么  # 遍历  # 美图  # ai  # kmp算法 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: Lar*el如何正确地在控制器和模型之间分配逻辑_Lar*el代码职责分离与架构建议  中兴Axon42Ultra怎样在文件App筛图_iPhone中兴Axon42Ultra文件App筛图【图片筛选】  在Pyomo中实现基于变量的条件约束:Big-M方法详解  怎样在Excel中做仪表盘_Excel仪表盘设计与关键指标展示方法  网站内容防复制粘贴的实现策略与局限性  sublime怎么格式化代码_sublime代码美化与一键排版插件配置  微信网页版登录教程_微信网页版登录入口在哪  抖音网页版快捷访问 抖音网页版网页版入口操作教程  Golang如何使用const iota_Go iota常量计数器讲解  Composer如何在生产环境安全地执行composer update  2026春节假期时间安排 2026春节假日查询  腾讯视频怎么使用多账号家庭管理_腾讯视频家庭多账号统一管理与权限分配教程  处理Kafka消费者会话超时:深入理解消息处理语义与幂等性  曝R星经典之作开发图 设计简陋但信息密集!  Lar*el头像管理:图片缩放与旧文件删除的最佳实践  c++如何使用TBB库进行任务并行_c++ Intel线程构建模块  Win11怎么安装Linux子系统 Win11 WSL2安装Ubuntu及环境配置指南  在Socket.IO连接中实现Access Token自动更新与动态重连  初次安装JDK时环境变量如何正确配置_J*A_HOME与PATH设置规则讲解  微博网页版怎么开启两步验证_微博网页版账号安全两步验证设置方法  谷歌google账号注册详细步骤 谷歌账号注册官方教程  Spring Boot嵌入式服务器与J*a EE:功能支持深度解析  Basecamp怎样用留言钉固定重点_Basecamp用留言钉固定重点【重点标记】  PyTorch模型训练准确率不提升:诊断与修复常见指标计算错误  邮政快递包裹最新位置 邮政快递实时追踪入口  小红书怎么解除第三方平台绑定_小红书多平台登录解绑方法介绍  Win11怎么设置开机NumLock亮 Win11修改注册表InitialKeyboardIndicators值  Go RPC HTTP服务正确实现与常见陷阱解析  圆通快递查询实时追踪 圆通物流包裹状态快速查看  React项目中导航栏Logo自适应布局:避免裁剪与布局溢出  微博网页版首页入口 微博电脑端官网登录链接  魅族17怎样用浏览器译外语网页_iPhone魅族17浏览器译外语网页【即时翻译】  从J*aScript对象中精确提取指定属性的教程  淘宝支付提示失败如何解决 淘宝支付流程优化方法  外媒分析《GTA6》定价:卖100美元可以但真没必要!  谷歌浏览器浏览体验优化_谷歌浏览器新版直连永久可用提示  c++中的const_cast和reinterpret_cast怎么用_c++四种类型转换  AngularJS $http POST请求数据传递与Go后端接收实践  Composer的 "conflict" 字段有什么用_如何声明不兼容的包以避免依赖冲突  如何在Promise链中有效终止错误处理后的执行  Spring Boot内嵌服务器与J*a EE全栈特性:选择与部署策略  QQ邮箱网页版入口 QQ邮箱官方邮箱登录通道  Lar*el Excel导入时生成自定义递增ID的策略与实践  Go语言中对Map值调用带指针接收者方法:原理与最佳实践  J*a递归快速排序中静态变量导致数据累积问题的解决方案  Bing引擎入口最新2025 Bing搜索免费官方登录  uc浏览器网页版入口 uc浏览器网页版最新网址  优酷会员付费后没到账怎么办_优酷会员充值异常及解决方法  Win11怎么查看电脑配置_Win11硬件配置检测工具使用  HTML空白字符处理机制:渲染、DOM与编码实践 

搜索