【板子】kmp #include iostream #include string #include vector using namespace std; // 求模式串p的next数组最长border vectorint getNext(const string p) { int n p.size(); vectorint next(n 1, 0); // next[1]~next[n] 对应长度1~n前缀 int j 0; for (int i 2; i n; i) { while (j 0 p[i - 1] ! p[j]) j next[j]; if (p[i - 1] p[j]) j; next[i] j; } return next; } // KMP匹配返回所有匹配起始位置1开头 vectorint kmpSearch(const string s, const string p, const vectorint next) { vectorint res; int n s.size(), m p.size(); int j 0; for (int i 1; i n; i) { while (j 0 s[i - 1] ! p[j]) j next[j]; if (s[i - 1] p[j]) j; // 完全匹配 if (j m) { res.push_back(i - m 1); // 左端点l1起始 j next[j]; } } return res; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); string s1, s2; cin s1 s2; auto next getNext(s2); auto pos kmpSearch(s1, s2, next); // 输出所有匹配位置 for (int x : pos) cout x \n; // 输出next[1]~next[m]空格分隔 int m s2.size(); for (int i 1; i m; i) { cout next[i] ; } return 0; }next特性len-next[len]是最小循环节优化失配数组#include iostream #include string #include vector using namespace std; vectorint getNext(const string p) { int n p.size(); vectorint next(n 1, 0); int j 0; for (int i 2; i n; i) { while (j 0 p[i - 1] ! p[j]) j next[j]; if (p[i - 1] p[j]) j; next[i] j; } return next; } // 生成nextval优化数组 vectorint getNextVal(const string p, const vectorint next) { int n p.size(); vectorint nextval(n 1, 0); nextval[1] 0; for (int i 2; i n; i) { int k next[i]; while (k 0 p[i - 1] p[k]) k next[k]; nextval[i] k; } return nextval; } // KMP匹配改用nextval vectorint kmpSearchVal(const string s, const string p, const vectorint nextval) { vectorint res; int n s.size(), m p.size(); int j 0; for (int i 1; i n; i) { while (j 0 s[i - 1] ! p[j]) j nextval[j]; if (s[i - 1] p[j]) j; if (j m) { res.push_back(i - m 1); j nextval[j]; } } return res; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); string s1, s2; cin s1 s2; auto next getNext(s2); auto nextval getNextVal(s2, next); auto pos kmpSearchVal(s1, s2, nextval); for (int x : pos) cout x \n; int m s2.size(); for (int i 1; i m; i) cout nextval[i] ; return 0; }KMP 完整原理分三层讲问题、暴力缺陷、next 数组、匹配流程、nextval 优化一、原始问题字符串模式匹配给定文本串 S长 n、模式串 P长 m找出 S 中所有 P 出现的位置。暴力匹配缺点两个指针 i文本、j模式匹配相等\(i,j\)失配i 回退到 \(i-j2\)j 归零 最坏复杂度 \(O(nm)\)如SaaaaaaaPaaab大量重复比较浪费时间。KMP 核心目标失配时文本指针 i 不回退只让模式指针 j 跳到最优位置整体线性 \(O(nm)\)。二、核心概念Border前缀函数 /next 数组1. 定义对模式串前 i 个字符组成的前缀 \(P[1,i]\)真前缀不包含最后一位真后缀不包含第一位\(next[i]\) 最长的长度 k满足前 k 位 后 k 位\(ki\)这个长度叫Border。例\(Pabcab\)长度 5 前缀a ab abc abca abcab 后缀b ab cab bcab abcab 最长相等真前后缀是ab长度 2 → \(next[5]2\)。2. next 数组求解逻辑1-based和你板子统一j 记录上一个前缀的最长 border 长度\(next[1]0\)单个字符无真前后缀i 从 2 遍历到 m若 \(P[i-1] \ne P[j]\)\(jnext[j]\) 回溯直到 \(j0\)匹配相等\(j\)\(next[i]j\)。 全程只前进不回退\(O(m)\) 求出 next。3. Border 的关键作用KMP 灵魂当匹配到 \(P[j]\) 和文本失配时 \(P[1,j-1]\) 是已经匹配成功的一段不需要全部重比。 利用 \(next[j-1]k\)说明 \(P[1,k] P[j-k,j-1]\)直接把 j 跳到 k文本指针 i 不动。举例 \(Pabcabc\)匹配到第 6 位失配\(next[6]3\)直接让 \(j3\)拿 \(P[3]\) 继续和当前文本字符对比省去从头匹配。三、KMP 匹配主流程设文本 S模式 Pi 文本下标j 模式下标循环遍历文本每个字符 \(S[i]\)失配且 \(j0\)\(jnext[j]\)若字符相等\(i,j\)当 \(jm\)模式完全匹配记录匹配起点\(jnext[j]\) 寻找重叠匹配比如aaaa中aa会多次匹配。全程 i 只增不减总复杂度 \(O(nm)\)。四、nextval优化失配数组原理问题普通 next 存在无效跳转例 \(Paaaaa\)\(next[4]3\)若 \(P[4]P[3]a\) 失配时跳到 \(j3\)字符还是 a依然失配多一次无用判断。nextval 优化规则对每个 i\(knext[i]\)若 \(P[i-1] P[k]\)继续令 \(knext[k]\)直到字符不等或 \(k0\)\(nextval[i]k\)。作用失配时一步跳到字符不同的位置减少比较次数卡常专用。五、拓展Border 衍生知识点1. 最小循环节字符串总长 L最长 border \(knext[L]\)循环节长度 \(dL-k\)。若 \(L \% d 0\)整个串由 \(L/d\) 个相同子串重复否则最小循环节是自身。 例abcabcabc\(L9,next[9]6,d3\)可由abc重复 3 次构成。2. 所有 Border 数量cnt 数组动物园题\(cnt[i]\) 前缀 i 所有合法 border 的总个数 递推式\(cnt[i] cnt[next[i]] 1\) 含义最长 border 最长 border 的所有 border。3. 不重叠 bordernum 数组NOI 动物园要求 \(2k \le i\)前后缀不重叠用双指针维护最大合法 k\(num[i]cnt[k]\)最后累乘 \((num[i]1)\) 得答案。

相关新闻

最新新闻

CNSH 排序不动点协议引擎 v1.0

CNSH 排序不动点协议引擎 v1.0

#!/usr/bin/env python3 # -*- coding: utf-8 -*-import os as _os import sys as _sys _module_dir _os.path.dirname(_os.path.abspath(__file__)) if _module_dir not in _sys.path:_sys.path.insert(0, _module_dir) """ CNSH 排序不动点协议引擎 v1.0 协议…

2026/7/7 16:37:52
PIC18F24K50与SLO2016嵌入式通信系统开发指南

PIC18F24K50与SLO2016嵌入式通信系统开发指南

1. 项目背景与核心器件解析在嵌入式系统开发领域,信息传递的可靠性和效率始终是工程师面临的核心挑战。PIC18F24K50作为Microchip Technology旗下经典的8位微控制器,配合SLO2016这类专用通信模块,能够构建高性价比的信息处理解决方案。PIC18F…

2026/7/7 16:37:52
云盘数据私有化指南:加密存储与在线播放的技术方案

云盘数据私有化指南:加密存储与在线播放的技术方案

你有没有想过,把存在阿里云盘、夸克网盘里的电影、照片、文档,变成一个只有你能访问的“私人媒体库”?不仅数据在云端是加密的,别人(包括服务商)都看不到内容,而且你还能在电脑上像操作本地文件…

2026/7/7 16:37:52
终极小说下载神器:3分钟掌握200+网站离线阅读全攻略

终极小说下载神器:3分钟掌握200+网站离线阅读全攻略

终极小说下载神器:3分钟掌握200网站离线阅读全攻略 【免费下载链接】novel-downloader 一个可扩展的通用型小说下载器。 项目地址: https://gitcode.com/gh_mirrors/no/novel-downloader 在数字阅读时代,小说爱好者最担心的莫过于心爱作品突然消失…

2026/7/7 16:37:52
模型更新策略:为什么“精度掉到某个值以下就重训”是错的?

模型更新策略:为什么“精度掉到某个值以下就重训”是错的?

在机器学习项目的生命周期中,模型更新(或称重新训练)是一个绕不开的核心议题。一个普遍存在的误区是:“当模型在测试集上的精度掉到某个阈值(比如90%)以下时,就该重新训练了。” 这种“精度触发…

2026/7/7 16:37:52
13DOF传感器与PIC32MZ微控制器实现厘米级定位

13DOF传感器与PIC32MZ微控制器实现厘米级定位

1. 项目背景与核心组件解析 在机器人导航和交互领域,精确定位一直是核心技术挑战。传统方案如UWB(超宽带)定位精度通常在10-30cm,而基于蓝牙的方案精度更低(约1米)。这个项目采用13DOF(九轴惯性…

2026/7/7 16:32:52

月新闻