当前位置: 首页 > article >正文

KMP 算法中 next 数组的构建函数 get_next

 KMP 算法中 next 数组的构建函数 get_next ,负责计算模式串的 next 数组,核心是通过递推找到每个位置的 “最长相等前缀后缀长度”。(下标从 1 开始):

一、函数作用

get_next(SString T, int next[]) 的任务:
为模式串 T 生成 next 数组,next[i] 表示 模式串中第 i 个字符失配时,应该回退到的位置(本质是 “前 i-1 个字符的最长相等前缀后缀长度”)。

二、代码逐行解析

void get_next(SString T, int next[]) {// 初始化:// i:模式串当前处理到的位置(从 1 开始,对应字符 T.ch[1])// j:记录当前最长相等前缀后缀的长度(初始为 0,对应“没有前缀”)i = 1; j = 0;  // next[1] 固定为 0(模式串第一个字符失配时,没有前缀可回退,特殊处理)next[1] = 0;  // 循环条件:i 遍历模式串的每个字符(直到模式串末尾)while (i < T.length) {  // 情况 1:j=0(回到起点) 或 当前字符匹配(T.ch[i] == T.ch[j])if (j == 0 || T.ch[i] == T.ch[j]) {  // i、j 同时后移,扩展匹配长度++i;  ++j;  // 记录 next[i]:当前最长相等前缀后缀长度是 jnext[i] = j;  } // 情况 2:当前字符不匹配(T.ch[i] != T.ch[j])else {  // j 回退到 next[j](找更短的前缀后缀继续匹配)j = next[j];  }}
}

三、核心逻辑拆解(结合递推思想)

  1. 初始化

    • i=1 从模式串第二个字符开始(第一个字符 next[1]=0 已固定)。
    • j=0 表示 “当前没有匹配的前缀”。
  2. 循环处理每个字符

    • 匹配时(T.ch[i] == T.ch[j]
      i 和 j 同时后移,next[i] = j 表示 “前 i 个字符的最长相等前缀后缀长度是 j”。
      例:模式串 ababc,当 i=3(字符 a)、j=1(字符 a)匹配时,i++=4j++=2next[4]=2(前 4 个字符 abab 的最长相等前缀后缀是 ab,长度 2)。

    • 失配时(T.ch[i] != T.ch[j]
      j = next[j] 让 j 回退到更短的前缀位置,继续尝试匹配。
      例:模式串 ababc,若 i=5(字符 c)、j=3(字符 a)失配,j = next[3] = 1(回退到更短的前缀),再比较 T.ch[5] 和 T.ch[1]

四、对于i,j可能不见名知意,有点混乱,那下面将它们换掉 ,并再次进行解释

①、重命名变量后的代码(下标从 1 开始)

// 生成模式串 T 的 next 数组
// next[position] 表示:当模式串在 position 位置失配时,应回退到的位置
void get_next(SString T, int next[]) {// current_pos:当前处理到模式串的哪个位置(初始从第二个字符开始)int current_pos = 1;// prefix_len:当前最长相等前缀的长度(初始为 0,表示无前缀)int prefix_len = 0;// 第一个字符失配时,只能回退到模式串开头(下标 0,实际代码中用 0 表示)next[1] = 0;// 遍历模式串的每个字符(从第二个开始,直到末尾)while (current_pos < T.length) {// 情况 1:prefix_len 回退到 0(回到起点),或者当前字符匹配成功if (prefix_len == 0 || T.ch[current_pos] == T.ch[prefix_len]) {// 继续匹配下一个字符current_pos++;prefix_len++;// 记录:当匹配到 current_pos 位置失配时,应回退到 prefix_len 位置next[current_pos] = prefix_len;}// 情况 2:当前字符匹配失败else {// 回退 prefix_len 到更短的前缀位置,继续尝试匹配prefix_len = next[prefix_len];}}
}

②、关键变量解释

原变量新变量含义
icurrent_pos当前处理到模式串的哪个位置(对应字符 T.ch[current_pos]
jprefix_len当前最长相等前缀的长度,也表示前缀的下一个待匹配位置(T.ch[prefix_len]
nextnext核心数组,next[pos] 表示模式串在 pos 位置失配时应回退到的位置

③、核心逻辑拆解(带例子)

以模式串 T = "ABABC"(下标从 1 开始)为例,逐步推导 next 数组:

1. 初始化
current_pos = 1;  // 处理第 1 个字符 'A'
prefix_len = 0;   // 无前缀
next[1] = 0;      // 第一个字符失配时,回退到 0(实际逻辑中表示从头开始)
2. 处理 current_pos = 1(字符 A
  • prefix_len = 0 → 进入 if 分支:

    current_pos++;  // 2
    prefix_len++;   // 1
    next[2] = 1;    // 表示:当匹配到第 2 个字符失配时,应回退到第 1 个字符
    
3. 处理 current_pos = 2(字符 B
  • T.ch[2] = 'B'T.ch[1] = 'A' → 不匹配 → 进入 else 分支:

    prefix_len = next[1] = 0;  // 回退到 0
    
  • 再次循环:prefix_len = 0 → 进入 if 分支:

    current_pos++;  // 3
    prefix_len++;   // 1
    next[3] = 1;    // 表示:当匹配到第 3 个字符失配时,应回退到第 1 个字符
    
4. 处理 current_pos = 3(字符 A
  • T.ch[3] = 'A'T.ch[1] = 'A' → 匹配 → 进入 if 分支:

    current_pos++;  // 4
    prefix_len++;   // 2
    next[4] = 2;    // 表示:当匹配到第 4 个字符失配时,应回退到第 2 个字符
    
5. 处理 current_pos = 4(字符 B
  • T.ch[4] = 'B'T.ch[2] = 'B' → 匹配 → 进入 if 分支:

    current_pos++;  // 5
    prefix_len++;   // 3
    next[5] = 3;    // 表示:当匹配到第 5 个字符失配时,应回退到第 3 个字符
    

四、总结

get_next 函数的核心逻辑:

  1. 匹配成功:扩展当前前缀长度,并记录 next 值。
  2. 匹配失败:回退到更短的前缀位置(通过 next 数组),继续尝试匹配。
http://www.lryc.cn/news/2402074.html

相关文章:

  • IDEA 开发PHP配置调试插件XDebug
  • 奇异值分解(SVD):线性代数在AI大模型中的核心工具
  • 矩阵分解相关知识点总结(二)
  • MySQL——视图 用户管理 语言访问
  • 二、Sqoop 详细安装部署教程
  • 用Python开启游戏开发之旅
  • React 第五十四节 Router中useRevalidator的使用详解及案例分析
  • 【C语言预处理详解(下)】--#和##运算符,命名约定,命令行定义 ,#undef,条件编译,头文件的包含,嵌套文件包含,其他预处理指令
  • 03.搭建K8S集群
  • RDMA简介3之四种子协议对比
  • 【最新版】西陆洗车系统源码全开源+uniapp前端+搭建教程
  • 力扣LeetBook数组和字符串--二维数组
  • Linux开发工具(apt,vim,gcc)
  • C# ExcelWorksheet 贴图
  • 鸿蒙Next开发真机调试签名申请流程
  • [yolov11改进系列]基于yolov11引入上下文锚点注意力CAA的python源码+训练源码
  • 【Elasticsearch】 查询优化方式
  • Xcode 16.4 + iOS 18 系统运行时崩溃:___cxa_current_primary_exception 符号丢失的原因与解决方案
  • 【linux】全志Tina预编译一个so库文件到根文件系统/usr/lib/下
  • C# 类和继承(成员访回修饰符)
  • c++ stl容器之map用法
  • Linux-文件管理及归档压缩
  • 结合Jenkins、Docker和Kubernetes等主流工具,部署Spring Boot自动化实战指南
  • 微软认证考试科目众多?该如何选择?
  • MCP协议在LLM系统中的架构与实现原理研究
  • Dify工作流实践—根据word需求文档编写测试用例到Excel中
  • 【LC实战派】小智固件编译
  • HTTP(超文本传输协议)详解
  • Unity安卓平台开发,启动app并传参
  • jdbcTemplate.query备忘录