在主串(长度 n)中找模式串(长度 m)的朴素匹配,最坏时间复杂度是?
规则:朴素匹配在每位尝试对齐模式串并逐字符比较,最坏 O(nm)。
考点:字符串匹配的朴素算法。
解析:主串 n 个起始位置,每个位置最多比 m 个字符,n×m。如主串 aaaa...a、模式 aa...ab,每次都到最后才发现失败。
易错:把朴素当 O(n);KMP 才是 O(n+m)。
排除法:O(n+m)、O(n) 是 KMP/哈希的复杂度;O(m log n) 与匹配无关。
字符串匹配问题:给定主串 S(长 n)和模式串 P(长 m),要在 S 中找?
规则:字符串匹配 = 在 S 中找 P 的(所有)出现位置。
考点:匹配问题定义。
解析:如 S=ababac、P=aba,匹配位置是 0 和 2。
排除法:最长公共子串是另一问题;最大字符/字典序后缀与匹配无关。
当 n、m 都达 10⁵ 时,朴素匹配(O(nm))会?
规则:n=m=10⁵ 时 O(nm)=10¹⁰ 超时,需要 KMP/哈希的 O(n+m)。
考点:匹配效率。
解析:10⁵×10⁵=10¹⁰ 远超 1 秒(约 10⁸ 次运算);KMP 线性完成。
排除法:不会编译失败;不是内存问题。
字符串匹配的规模
规则:暴力 = 外层 n-m+1 个起始位 × 内层逐字符比较 m 个。
考点:匹配算法结构。
解析:对每个主串位置 i,尝试把模式 P 与 S[i..i+m-1] 对齐比较。
排除法:内层是比模式;不只一次;模式不自己枚举。
匹配的语义
规则:出现 = 连续子串完全相等:S 从 i 起连续 |P| 个字符 == P。
考点:匹配定义。
解析:S=abc、P=bc,出现位置 i=1(S[1..2]=bc==P)。
排除法:只比首字符/子序列/尾字符都不对。
子串 vs 子序列
规则:子串 = 连续一段;子序列 = 按原序取任意字符(可不连续)。
考点:子串子序列。
解析:abc 的子串:a、b、c、ab、bc、abc;子序列还可 ac(跳过 b)。
排除法:方向反;不相同;不要求全含。
模式串与主串
规则:主串 S(被查找的较长串)、模式串 P(要找的较短串)。
考点:术语。
解析:在 S 中找 P;|S|=n ≥ |P|=m。
排除法:主串长模式短。
匹配位置的个数
规则:可重叠计数:位置 0(aba)和位置 2(aba,与前者重叠一个 a)。
考点:重叠匹配。
解析:S=ababa、P=aba:S[0..2]=aba ✓;S[2..4]=aba ✓。共 2 次。
排除法:1 漏重叠;3/4 数错。
暴力匹配的剪枝
规则:暴力 = 失配则主串起始位 +1,模式从头再比。
考点:暴力匹配流程。
解析:这是暴力的最大浪费——已匹配的前缀信息被丢弃。
排除法:下一位重比是暴力;KMP 才不回退。
KMP 优化的核心
规则:已匹配的 P[0..j-1] 中,其后缀可能等于其前缀,失配时模式直接跳到前缀处,不用重比。
考点:KMP 核心思想。
解析:匹配 abab 时主串末尾 ab 已对上,失配可复用这个 ab。
排除法:主串后缀/字典序/哈希都不是 KMP 的优化依据。
next 数组的长度
规则:next[i] 对应 P[0..i],共 m 个元素(下标 0~m-1)。
考点:next 数组规模。
解析:next[0..m-1] 长度 m。
排除法:m-1/m+1/2m 都不对。
前缀函数的用途
规则:前缀函数 π[i] = P[0..i] 的最长相等真前后缀长度。
考点:前缀函数定义。
解析:它让失配时能跳回已匹配的相等部分,避免重比。
排除法:后缀/ASCII/字典序都无关。
匹配的判定输出
规则:匹配常见输出 = 出现位置(首个/全部)或次数。
考点:匹配输出。
解析:题面会指定:返回首次出现下标 / 计数 / 全部位置。
排除法:长度/频次/后缀非匹配输出。
KMP 处理的问题类型
规则:KMP 专治「在一个串中找另一个串的(所有)出现」。
考点:KMP 适用。
解析:病毒扫描、词频统计、字符串过滤都用 KMP。
排除法:回文用 Manacher;编辑距离用 DP;排序无关。
暴力 vs KMP 对比
规则:nm=10¹⁰、n+m=2×10⁵,暴力慢约 5×10⁴ 倍。
考点:复杂度对比。
解析:10¹⁰ 远超 1 秒预算;KMP 毫秒级。
排除法:不是 2 倍/差不多/KMP 更慢。
匹配的最坏输入
规则:S=aaaa...a、P=aaaa...b——每个起始位都比满 m 个。
考点:暴力最坏情形。
解析:n-m+1 个起始位 × m 次比较 = O(nm)。
排除法:空串/模式更长/随机都不触发最坏。
string 下标约定
规则:C++ string 下标 0 起(s[0] 首字符),长度 s.size()。
考点:string 下标。
解析:string s = abc 时 s[0] 是 a。与部分题目「下标 1 起」约定不同,做题看题面。
排除法:0 起是 C++ 标准。
字符串比较
规则:string 按字典序比较:逐字符比,第一个不同的字符决定大小。
考点:字符串比较。
解析:a=abc、b=abd 的前两字符同,第三 c<d → a<b。
排除法:不比长度/首字符/随机。
字符串拼接
规则:+ / += 拼接字符串。
考点:字符串操作。
解析:s 从 a 变 ab;s.size()=2。
排除法:不是字面 a+b;不是倒序;不报错。
find 函数
规则:s.find(子串) 返回首次出现下标;找不到返回 string::npos(巨大值)。
考点:string find。
解析:hello 中 ll 在位置 2(h0 e1 l2)。
易错:找不到不是 -1 而是 npos,判断用 == string::npos。
排除法:3/0 错;不是 -1。
substr 函数
规则:substr(起始, 长度) 截取子串。
考点:substr。
解析:abcdef.substr(2,3) = 从下标 2 取 3 个 = cde。
排除法:bcd 是从 1 取 3;cd 长度错;abc 起点错。
reverse 与回文
规则:回文判等 = s 与反转后相同;或双指针 i、j 从两端向中间比。
考点:回文判断。
解析:aba 反转 aba 相同 → 回文。
排除法:排序/最长子串/栈都不是判回文的直接方法。
toupper/tolower
规则:C++ 无 string.toUpper(),需遍历字符逐个 toupper(c)。
考点:字符大小写。
解析:for(char& c : s) c = toupper(c);(注意 char 有符号问题)。
排除法:无 toUpper 方法;+=32 不规范;sort 无关。
getline 读取
规则:cin>>s 遇空格停;getline(cin,s) 读整行含空格。
考点:字符串输入。
解析:输入 hello world,cin>>s 得 hello,getline 得 hello world。
排除法:>> 不读空格;gets 已废弃;cin.get 是字符。
string 与 char 数组
规则:string 封装了长度与操作(拼接/比较/查找),更安全好用。
考点:string vs char 数组。
解析:s1+s2、s1==s2、s.find() 都是 string 便利处。
排除法:string 未必更快/更省;可变长。
字符串 abacaba 的一个「真前缀」是?
规则:前缀 = 从开头取的连续子串;真前缀 ≠ 整个串。
考点:前缀后缀概念。
解析:aba 是 abacaba 的真前缀(取前 3 个);abacabaa 比原串还长不可能;acaba、bacaba 不以开头取。
排除法:后缀/加长/错位都不是前缀。
KMP 中模式串 P=abacaba 的 next 数组(next[i] = P[0..i] 最长相等前后缀长度,下标从 0 起)是?
规则:next[i] = P[0..i] 的最长相等前后缀长度(不含整串)。
考点:KMP next 数组(真题 2025 原题)。
解析:逐位算:
易错:前缀和后缀不能取整串;abacab 的最长相等前后缀是 ab(2)不是 a。
排除法:其余选项是递增/错位的结果。
KMP 匹配过程中,主串指针 i 匹配到 P[j] 失配(S[i]≠P[j])时,应执行?
规则:失配时主串指针 i 不回退,只把模式串指针 j 跳到 next[j-1](已匹配前缀的相等部分)。
考点:KMP 失配跳转。
解析:P[0..j-1] 已匹配,其后缀等于前缀,所以直接跳 j=next[j-1] 继续比,i 不动——这就是 KMP 线性(O(n+m))的关键。
易错:i 回退 = 朴素匹配的缺点,KMP 恰恰避免了它。
排除法:i 不回退;j 不直接清零(跳 next 更聪明);j/i 不递减。
KMP 匹配的总时间复杂度是?
规则:KMP = 预处理 next O(m) + 匹配 O(n) = O(n+m)。
考点:KMP 复杂度。
解析:i 只前进不回退(至多 n 步),j 的跳转摊还也 O(n),总线性。
易错:误以为 j 跳转会退化——均摊后仍线性。
排除法:nm 是朴素;n log m、m² 与 KMP 不符。
KMP 的 next 数组构造函数:
01void build_next(const string& p, int next[]) { 02 next[0] = 0; 03 int j = 0; 04 for (int i = 1; i < (int)p.size(); i++) { 05 while (j > 0 && p[i] != p[j]) j = next[j - 1]; 06 if (p[i] == p[j]) j++; 07 next[i] = j; 08 } 09}
abab,函数结束后 next 数组是?
规则:build_next 用变量 j 表示「已匹配的相等前后缀长度」,循环里失配回退、相等前进。
考点:next 构造代码追踪。
解析:逐位跑:
易错:j 是「当前匹配到的前缀长度」,next[i] 直接取它;失配才进 while 回退。
排除法:{0,0,1,1} 少算了 abab 的 ab=ab(长度 2);递增/少 0 是错的。
仍看 build_next 代码。P = abacab,当 i=5 时(p[5]=b,j 此时为 2,p[2]=a),p[i]≠p[j],while 回退后 j 变为?
规则:失配时 j = next[j-1],j-1=1 的 next 是 0,所以 j 回退到 0。
考点:build_next 失配回退。
解析:i=5 前已算:next={0,0,1,0,1}。i=5:p[5]=b vs p[j=2]=a 不等 → j=next[1]=0;再比 p[5]=b vs p[0]=a 不等;j=0,next[5]=0。
易错:回退到 next[j-1] 不是清零到 0 一步到位,而是可能多次;这里恰好一次到 0。
排除法:next[1]=0 所以回退到 0;1/2/3 都是没正确查 next。
KMP 匹配函数:
01int kmp(const string& s, const string& p, int next[]) { 02 int n = s.size(), m = p.size(); 03 int j = 0, cnt = 0; 04 for (int i = 0; i < n; i++) { 05 while (j > 0 && s[i] != p[j]) j = next[j - 1]; 06 if (s[i] == p[j]) j++; 07 if (j == m) { cnt++; j = next[j - 1]; } 08 } 09 return cnt; 10}
ababab、模式 P = aba(next = {0,0,1}),函数返回的匹配次数是?
规则:匹配到完整模式后 cnt+1 并 j 回退到 next[j-1](重叠匹配)。
考点:KMP 匹配代码追踪。
解析:逐位:
易错:匹配后 j 回退到 next[j-1] 允许重叠匹配(ababab 里 aba 出现 2 次)。
排除法:1 是漏掉重叠;3/4 是数错。
字符串哈希代码:
01unsigned long long h[105], pw[105]; 02void init_hash(const string& s, int B) { 03 pw[0] = 1; 04 for (int i = 0; i < (int)s.size(); i++) { 05 pw[i + 1] = pw[i] * B; 06 h[i + 1] = h[i] * B + s[i]; 07 } 08}
ab(ASCII a=97, b=98)、B = 3,运行后 h[2] 的值是?
规则:h[i+1] = h[i]×B + s[i],即把串当 B 进制数逐位累加。
考点:哈希代码追踪。
解析:pw[1]=3,pw[2]=9;h[1]=0×3+97=97;h[2]=97×3+98=291+98=389。即 97×3+98=389,ab 在 B=3 下的哈希。
易错:字符参与的是 ASCII 数值(97/98),不是 'a' 当 1。
排除法:98 是 b 的 ASCII;195 是 97+98;291 少加了 98(只算到 a×3)。
接上题 init_hash 后,子串哈希查询:
01unsigned long long get_hash(int l, int r) { // 求 s[l..r] 的哈希 02 return h[r + 1] - h[l] * pw[r - l + 1]; 03}
abc(ASCII a=97,b=98,c=99)、B = 3(h:h[1]=97, h[2]=389, h[3]=389×3+99=1266),get_hash(1, 2)(即 bc)的值是?
规则:get_hash(l,r) = h[r+1] − h[l]·B^(r−l+1),把 l 之前的位「挪走」。
考点:子串哈希代码追踪。
解析:get_hash(1,2) = h[3] − h[1]×pw[2] = 1266 − 97×9 = 1266 − 873 = 393。验证:bc = 98×3+99 = 294+99 = 393 ✓。
易错:pw 的指数是子串长 r−l+1=2(不是 l);h[l] 乘的是 pw[2]。
排除法:389 是 ab 的哈希;487 是 1266−389 错减;1266 是整串哈希。
Manacher 求最长回文子串长度:
01int manacher(string s) { 02 string t = "#"; 03 for (char c : s) { t += c; t += '#'; } 04 vector<int> d(t.size()); 05 int l = 0, r = -1, ans = 0; 06 for (int i = 0; i < (int)t.size(); i++) { 07 int k = (i > r) ? 1 : min(d[l + r - i], r - i + 1); 08 while (i - k >= 0 && i + k < (int)t.size() && t[i - k] == t[i + k]) k++; 09 d[i] = k; 10 if (i + k - 1 > r) { l = i - k + 1; r = i + k - 1; } 11 ans = max(ans, d[i] - 1); 12 } 13 return ans; 14}
aba,函数返回的最长回文子串长度是?
规则:插入 # 后统一处理奇偶回文;d[i] 是 t 中以 i 为中心的回文半径,原串半径 = d[i]−1。
考点:Manacher 代码追踪。
解析:t = #a#b#a#。中心 i=3(字符 b):向两边扩,#a#b#a# 全部对称,k=4,d[3]=4,对应原串半径 d−1=3(aba)。ans=3。
易错:d[i] 是「含中心」的半径(#a#b#a# 半径 4),原串回文长度 = d−1。
排除法:2/1 是部分回文;5 是插入 # 后的 t 长度。
构造 next 数组的核心逻辑:设 next[i] 已知,用变量 j 表示当前最长相等前后缀长度,当 P[i] 与 P[j] 不等时,j 应?
规则:构造 next 时失配,j 回退到 next[j-1] 继续尝试,与匹配阶段同一套路。
考点:next 构造。
解析:next 构造本质是「模式串自己匹配自己」:P[i]==P[j] 则 next[i]=++j;不等则 j 回退再比。
排除法:清零会丢已算的前缀信息;加一/置 i 都错。
对 P = aabaaac 运行 build_next(next[0]=0,失配回退 next[j-1]),next 数组是?
// 上一题 build_next 同款
考点:模板代码:build_next 完整。
解析:见题面情境,按模板代码:build_next 完整 的规则推演可得答案(正确项为 0,1,0,1,2,2,3)。
排除法:其余选项是常见误解/错位结果。
P = aabaaab 中 build_next 构造,当 i=6(P[6]=b)时若 P[6]≠P[j](j=2 处是 b?),j 的完整回退链是?
考点:模板代码:失配多级回退。
解析:见题面情境,按模板代码:失配多级回退 的规则推演可得答案(正确项为 按 next[1]、next[0] 逐级回退到 j=0 或匹配)。
排除法:其余选项是常见误解/错位结果。
KMP 匹配到 j==m(完整匹配)后,j 更新为 next[j-1],这样做的目的是?
考点:模板代码:next 与匹配联动。
解析:见题面情境,按模板代码:next 与匹配联动 的规则推演可得答案(正确项为 允许重叠匹配(计数全部出现))。
排除法:其余选项是常见误解/错位结果。
字符串哈希用 int 手写取模(mod=1e9+7)相比 ull 自然溢出,需要额外注意?
考点:模板代码:哈希取模写法。
解析:见题面情境,按模板代码:哈希取模写法 的规则推演可得答案(正确项为 每步乘加后取模,防止溢出)。
排除法:其余选项是常见误解/错位结果。
双哈希(两个 base 或两个 mod)的作用是?
考点:模板代码:双哈希。
解析:见题面情境,按模板代码:双哈希 的规则推演可得答案(正确项为 把碰撞概率降到可忽略)。
排除法:其余选项是常见误解/错位结果。
用哈希判「两个长度为 k 的子串是否相同」,步骤是?
考点:模板代码:字符串哈希找重复子串。
解析:见题面情境,按模板代码:字符串哈希找重复子串 的规则推演可得答案(正确项为 分别求哈希(O(1) 用前缀哈希)再比较)。
排除法:其余选项是常见误解/错位结果。
字符串哈希做匹配(比较每个窗口哈希)与 KMP 相比?
考点:模板代码:哈希匹配与 KMP 对比。
解析:见题面情境,按模板代码:哈希匹配与 KMP 对比 的规则推演可得答案(正确项为 哈希 O(n+m) 且实现简单,但有极小碰撞风险;KMP 无碰撞)。
排除法:其余选项是常见误解/错位结果。
Manacher 里 d[i] 表示 t(含 # 的串)中以 i 为中心的回文半径(含中心字符数)。原串回文长度 = d[i]-1 是因为?
考点:模板代码:Manacher 半径含义。
解析:见题面情境,按模板代码:Manacher 半径含义 的规则推演可得答案(正确项为 # 让奇偶回文统一,半径含 # 和中心,减 1 得原串长度)。
排除法:其余选项是常见误解/错位结果。
Manacher 中 l、r 记录当前最右回文的左右边界,其作用是?
考点:模板代码:Manacher 边界。
解析:见题面情境,按模板代码:Manacher 边界 的规则推演可得答案(正确项为 对称复用边界内位置的半径,避免重复扩展)。
排除法:其余选项是常见误解/错位结果。
Manacher 处理长 n 的串,时间复杂度是?
考点:模板代码:Manacher 复杂度。
解析:见题面情境,按模板代码:Manacher 复杂度 的规则推演可得答案(正确项为 O(n)(每个位置扩展摊还线性))。
排除法:其余选项是常见误解/错位结果。
KMP 统计所有匹配位置,当 j==m 时除了 cnt++ 还应?
考点:模板代码:KMP 匹配位置输出。
解析:见题面情境,按模板代码:KMP 匹配位置输出 的规则推演可得答案(正确项为 记录 i-m+1(当前匹配起点),再 j=next[j-1])。
排除法:其余选项是常见误解/错位结果。
字符串哈希 mod 通常取大素数(如 1e9+7)而非 1e5,原因是?
考点:模板代码:哈希与 mod 选取。
解析:见题面情境,按模板代码:哈希与 mod 选取 的规则推演可得答案(正确项为 减少哈希碰撞概率)。
排除法:其余选项是常见误解/错位结果。
用 int 取模哈希求子串时,若 base 与 mod 互素,除法(h[r]-h[l]*B^len)为什么不需要逆元?
考点:模板代码:字符串哈希与逆元。
解析:见题面情境,按模板代码:字符串哈希与逆元 的规则推演可得答案(正确项为 因为子串哈希用「乘 B^len 再减」而非除法)。
排除法:其余选项是常见误解/错位结果。
处理 10⁵ 级文本中找 10 个模式串的首次出现,简单可靠的做法?
考点:模板代码:KMP 与字符串哈希选型。
解析:见题面情境,按模板代码:KMP 与字符串哈希选型 的规则推演可得答案(正确项为 对每个模式用 KMP 或哈希各跑一遍(O(10(n+m))))。
排除法:其余选项是常见误解/错位结果。
字符串哈希的核心思想是?
规则:哈希 = 把字符串按「多项式/进制」映射成一个整数(如 ),两串相等 → 哈希值相等(一般可反推相等)。
考点:字符串哈希思想。
解析:预处理前缀哈希,可 O(1) 求任意子串哈希,用于判等/找重复。
易错:哈希有极小碰撞可能,严格判等可双哈希/再比对原串。
排除法:不是还原/排序/压缩。
预处理前缀哈希 h[i](s[0..i-1] 的哈希)后,求子串 s[l..r] 的哈希(base=B)的公式是?
规则:子串哈希 = 前缀哈希差分:h[r+1] − h[l]·B^(len),把 l 之前的位「挪走」。
考点:子串哈希公式。
解析:h[l] 在低位,乘以 B^(r-l+1) 对齐到 h[r+1] 的高位,相减留下 s[l..r] 的贡献。
易错:幂次是 r−l+1(子串长)不是 l;方向别反。
排除法:加减法/错位幂都得不到正确子串哈希。
字符串哈希最适合解决哪类问题?
规则:哈希把子串判等降到 O(1),适合需要大量子串比较的场景(不同子串数、模式匹配近似)。
考点:哈希应用。
解析:如「统计长为 k 的不同子串」——对每个子串取哈希去重即可。
排除法:LCS 用 DP;排序用 sort;压缩是另一回事。
Manacher 算法能在 O(n) 内求出?
规则:Manacher 线性求每个位置为中心的最长回文半径,从而求最长回文子串。
考点:Manacher(KS-59b)。
解析:用对称性复用已算的半径,把朴素的 O(n²) 回文枚举降到 O(n)。
排除法:LIS 是 DP;最小表示/编辑距离都非回文问题。
朴素枚举所有回文子串是 O(n²)(枚举中心+向两边扩),Manacher 优化到 O(n) 靠的是?
规则:Manacher 维护最右边界,边界内的回文半径由对称位置直接得到,不再重复扩展。
考点:Manacher 原理。
解析:中心对称的回文串,其内部位置的回文半径可镜像复用,摊还线性。
排除法:中心数没变(还是 2n-1 个);不用二分/排序。
统计长度 k 的不同子串个数,用哈希的做法?
考点:应用:字符串哈希统计不同子串。
解析:见题面情境,按应用:字符串哈希统计不同子串 的规则推演可得答案(正确项为 把每个子串哈希放入 unordered_set,去重取 size)。
排除法:其余选项是常见误解/错位结果。
用哈希快速判断 s[l1..] 与 s[l2..] 从开头能匹配多长,常用?
考点:应用:最长公共前缀哈希。
解析:见题面情境,按应用:最长公共前缀哈希 的规则推演可得答案(正确项为 二分长度 + O(1) 哈希判等)。
排除法:其余选项是常见误解/错位结果。
字符串哈希中,两个子串哈希相等(用同 base 同 mod)就判定相等,风险是?
考点:应用:哈希判断子串相等。
解析:见题面情境,按应用:哈希判断子串相等 的规则推演可得答案(正确项为 碰撞:不同子串可能哈希相同)。
排除法:其余选项是常见误解/错位结果。
KMP 中,n-next[n-1] 能表示字符串的最小循环节长度的条件是?
考点:应用:KMP 求循环节。
解析:见题面情境,按应用:KMP 求循环节 的规则推演可得答案(正确项为 n % (n-next[n-1]) == 0 时,该值是最小循环节)。
排除法:其余选项是常见误解/错位结果。
主串长 n、模式长 m,KMP 统计出现次数的时间是?
考点:应用:KMP 统计子串出现。
解析:见题面情境,按应用:KMP 统计子串出现 的规则推演可得答案(正确项为 O(n+m))。
排除法:其余选项是常见误解/错位结果。
Manacher 对 s=abccba 求出的最长回文子串长度是?
考点:应用:Manacher 求最长回文子。
解析:见题面情境,按应用:Manacher 求最长回文子 的规则推演可得答案(正确项为 6(整个 abccba))。
排除法:其余选项是常见误解/错位结果。
求所有回文子串个数,Manacher 能做的依据是?
考点:应用:回文中心个数。
解析:见题面情境,按应用:回文中心个数 的规则推演可得答案(正确项为 每个 d[i] 直接给出以 i 为中心的回文半径,个数可累加)。
排除法:其余选项是常见误解/错位结果。
按字典序排序 n 个字符串,用 string 的 < 直接 sort,复杂度?
考点:应用:字符串哈希与排序。
解析:见题面情境,按应用:字符串哈希与排序 的规则推演可得答案(正确项为 O(总字符数 log n)(比较是 O(L) 但可接受))。
排除法:其余选项是常见误解/错位结果。
求字符串循环同构的最小字典序(最小表示法)的复杂度是?
考点:应用:字符串的最小表示。
解析:见题面情境,按应用:字符串的最小表示 的规则推演可得答案(正确项为 O(n))。
排除法:其余选项是常见误解/错位结果。
大量字符串(总长 10⁶)快速排序,可用哈希优化的思路是?
考点:应用:字符串排序的哈希优化。
解析:见题面情境,按应用:字符串排序的哈希优化 的规则推演可得答案(正确项为 先比较哈希值(O(1))粗排,同哈希再逐字符确认)。
排除法:其余选项是常见误解/错位结果。
数据 10⁶、模式串固定、需匹配 10⁶ 次,每次用 KMP 重跑?
考点:应用:字符串哈希与模式匹配选型。
解析:见题面情境,按应用:字符串哈希与模式匹配选型 的规则推演可得答案(正确项为 不行,应预处理一次或哈希 O(1) 判等)。
排除法:其余选项是常见误解/错位结果。
为什么竞赛中字符串哈希「偶发碰撞」可接受?
考点:应用:哈希碰撞的极端情形。
解析:见题面情境,按应用:哈希碰撞的极端情形 的规则推演可得答案(正确项为 概率极低(mod 1e9+7 下约 1e-9),且通常数据非构造对抗)。
排除法:其余选项是常见误解/错位结果。
字符串 s 的最小周期(前缀重复)与 next 的关系,正确的是?
考点:应用:KMP 与周期。
解析:见题面情境,按应用:KMP 与周期 的规则推演可得答案(正确项为 若 n%(n-next[n-1])==0,周期为 n-next[n-1],否则无完整周期)。
排除法:其余选项是常见误解/错位结果。
判断子串 s[l..r] 是否回文,用哈希的技巧是?
考点:应用:字符串哈希求回文。
解析:见题面情境,按应用:字符串哈希求回文 的规则推演可得答案(正确项为 正反各建哈希,比较正串哈希与反串对应哈希)。
排除法:其余选项是常见误解/错位结果。
Manacher 给 s 插入 # 的目的?
考点:应用:Manacher 预处理。
解析:见题面情境,按应用:Manacher 预处理 的规则推演可得答案(正确项为 让奇偶长度回文统一为奇数处理)。
排除法:其余选项是常见误解/错位结果。
「求最长公共子串」可用哈希+二分,做法是?
考点:应用:字符串哈希与二分答案。
解析:见题面情境,按应用:字符串哈希与二分答案 的规则推演可得答案(正确项为 二分长度 L,哈希判是否存在两串长度为 L 的相等子串)。
排除法:其余选项是常见误解/错位结果。
模式串含通配符(如 a?b),用 KMP 直接匹配?
考点:应用:KMP 与字符串哈希的选择。
解析:见题面情境,按应用:KMP 与字符串哈希的选择 的规则推演可得答案(正确项为 不能,通配符破坏相等比较,需改造或另法)。
排除法:其余选项是常见误解/错位结果。
字符串哈希中「滑动窗口」求下一窗口哈希的递推是?
考点:应用:字符串哈希与滑动窗口哈希。
解析:见题面情境,按应用:字符串哈希与滑动窗口哈希 的规则推演可得答案(正确项为 h_new = (h_old - s[l]*B^k)*B + s[r+1])。
排除法:其余选项是常见误解/错位结果。
字符串哈希 base 取 131/13331 而不用 2 或 10,原因是?
考点:应用:字符串哈希的 base 选择。
解析:见题面情境,按应用:字符串哈希的 base 选择 的规则推演可得答案(正确项为 更大 base 减少碰撞,且非 2 幂避免与 mod 关联)。
排除法:其余选项是常见误解/错位结果。
AC 自动机(多模式 KMP)适合?
考点:应用:多模式匹配规模。
解析:见题面情境,按应用:多模式匹配规模 的规则推演可得答案(正确项为 一次匹配多个模式串(如敏感词过滤))。
排除法:其余选项是常见误解/错位结果。
KMP 的 next[i] 与「模式串前 i 个字符的最长公共前后缀」的关系,下列说法正确的是?
规则:next 数组有两种下标约定(从 0 起/从 1 起,next[i] 指 P[0..i] 或 P[0..i-1]),但本质都是最长相等前后缀。
考点:next 定义辨析。
解析:做题时先看题目给出的 next 定义再算(真题 2025 明确 next[i]=P[0..i] 最长相等前后缀,下标 0 起)。
易错:不同教材 next 起算下标不同,结果数组首位可能差 1。
排除法:是最长不是最短;与前后缀密切相关;next[i]≠i。
两个不同字符串可能得到相同哈希值,这叫做?
规则:不同输入映射到相同哈希值 = 哈希冲突。
考点:哈希冲突概念。
解析:哈希把无限字符串映射到有限整数,冲突不可避免;应对 = 双哈希(两个 base/mod)或冲突时回源串比对。
排除法:溢出是数值超限;失配/重叠是匹配术语。
用字符串哈希实现「在主串 S 中找模式串 P」,正确的做法是?
规则:哈希匹配 = 预处理 S 的前缀哈希,O(1) 取每个窗口子串哈希与 P 哈希比,总 O(n+m)。
考点:哈希匹配应用。
解析:滑动窗口 n−m+1 个子串,每个 O(1) 取哈希,命中再(可选)回源串确认防碰撞。
排除法:排序/回文都不是匹配做法。
CSP-S 中 KMP 与朴素匹配的选择,正确的是?
规则:数据规模大(10⁵ 级)必须 O(n+m) 的 KMP 或哈希;小规模朴素即可。
考点:算法选型。
解析:真题 2022 阅读程序考的就是 KMP 实现与复杂度;选型看数据规模。
排除法:朴素在大数据超时;KMP 需求与模式长短无关;哈希能做匹配。
不同教材 next 数组下标起始不同,做题时必须?
考点:易错:next 的边界定义。
解析:见题面情境,按易错:next 的边界定义 的规则推演可得答案(正确项为 先看题面给的 next 定义(对 P[0..i] 还是 P[0..i-1]、下标 0/1 起))。
排除法:其余选项是常见误解/错位结果。
string s 中 s[i] 的类型是?
考点:易错:字符串与字符。
解析:见题面情境,按易错:字符串与字符 的规则推演可得答案(正确项为 char(单个字符))。
排除法:其余选项是常见误解/错位结果。
空字符串(长度 0)在匹配/哈希中,以下说法正确的是?
考点:易错:空串。
解析:见题面情境,按易错:空串 的规则推演可得答案(正确项为 空串是任何串的子串,匹配空串返回 0)。
排除法:其余选项是常见误解/错位结果。
模式串中含 '.'(普通字符,非通配)时 KMP 直接匹配?
考点:易错:KMP 与模式含特殊字符。
解析:见题面情境,按易错:KMP 与模式含特殊字符 的规则推演可得答案(正确项为 可以,'.' 就是普通字符参与 == 比较)。
排除法:其余选项是常见误解/错位结果。
两段子串哈希比较时 base 幂次不一致,结果?
考点:易错:哈希值比较用错 base。
解析:见题面情境,按易错:哈希值比较用错 base 的规则推演可得答案(正确项为 哈希不可比(幂次对齐才可比))。
排除法:其余选项是常见误解/错位结果。
int 哈希不取模直接乘加会?
考点:易错:哈希溢出误判。
解析:见题面情境,按易错:哈希溢出误判 的规则推演可得答案(正确项为 溢出成随机值,判等失效)。
排除法:其余选项是常见误解/错位结果。
Manacher 扩展 while 里条件 i-k>=0 && i+k<t.size() 防止?
考点:易错:Manacher 数组越界。
解析:见题面情境,按易错:Manacher 数组越界 的规则推演可得答案(正确项为 数组越界)。
排除法:其余选项是常见误解/错位结果。
KMP 处理多个不同模式串的最优做法?
考点:易错:KMP 与多模式。
解析:见题面情境,按易错:KMP 与多模式 的规则推演可得答案(正确项为 每个模式单独跑 KMP(总 O(Σ(n+mi))),或 AC 自动机)。
排除法:其余选项是常见误解/错位结果。
string 的 < 是字典序,与「长度优先」的区别?
考点:易错:字符串比较的字典序。
解析:见题面情境,按易错:字符串比较的字典序 的规则推演可得答案(正确项为 字典序先比字符,长度只在前面全同才比)。
排除法:其余选项是常见误解/错位结果。
string::find 找不到返回的值是?
考点:易错:find 返回值类型。
解析:见题面情境,按易错:find 返回值类型 的规则推演可得答案(正确项为 string::npos(巨大 unsigned 值))。
排除法:其余选项是常见误解/错位结果。
s.substr(pos, len) 当 pos+len 超过长度时?
考点:易错:substr 越界。
解析:见题面情境,按易错:substr 越界 的规则推演可得答案(正确项为 返回从 pos 到末尾的子串(不越界报错))。
排除法:其余选项是常见误解/错位结果。
字符串哈希 base 取负数?
考点:易错:哈希与负数 base。
解析:见题面情境,按易错:哈希与负数 base 的规则推演可得答案(正确项为 不行,哈希不稳定且幂次符号交替)。
排除法:其余选项是常见误解/错位结果。
「next 数组」和「最小循环节」的关系,正确说法?
考点:易错:KMP next 与循环节混淆。
解析:见题面情境,按易错:KMP next 与循环节混淆 的规则推演可得答案(正确项为 next 是前后缀信息,循环节由 n-next[n-1] 整除条件推出)。
排除法:其余选项是常见误解/错位结果。
Manacher 处理后 t 的长度是 2n+1,d 数组长度?
考点:易错:Manacher 与字符串长度。
解析:见题面情境,按易错:Manacher 与字符串长度 的规则推演可得答案(正确项为 2n+1(与 t 等长))。
排除法:其余选项是常见误解/错位结果。
比较长度不同的两个子串哈希?
考点:易错:哈希与字符串长度差。
解析:见题面情境,按易错:哈希与字符串长度差 的规则推演可得答案(正确项为 需先判长度相等,长度不同哈希不同且不可直接比)。
排除法:其余选项是常见误解/错位结果。
匹配时区分大小写?
考点:易错:KMP 与输入大小写。
解析:见题面情境,按易错:KMP 与输入大小写 的规则推演可得答案(正确项为 默认区分,'a'≠'A';不区分需先统一大小写)。
排除法:其余选项是常见误解/错位结果。
base 取 0 会?
考点:易错:字符串哈希与 base=0。
解析:见题面情境,按易错:字符串哈希与 base=0 的规则推演可得答案(正确项为 所有串哈希都是 0,判等完全失效)。
排除法:其余选项是常见误解/错位结果。
Manacher 求出的最长回文子串长度类型?
考点:易错:Manacher 答案类型。
解析:见题面情境,按易错:Manacher 答案类型 的规则推演可得答案(正确项为 int(原串长度,≤n))。
排除法:其余选项是常见误解/错位结果。
字符串匹配数据 10⁶ 时,朴素 O(nm) 会?
考点:易错:字符串题的数据范围。
解析:见题面情境,按易错:字符串题的数据范围 的规则推演可得答案(正确项为 超时,须 KMP/哈希)。
排除法:其余选项是常见误解/错位结果。
取模后哈希出现负值?
考点:易错:哈希与 mod 负数。
解析:见题面情境,按易错:哈希与 mod 负数 的规则推演可得答案(正确项为 C++ % 负数结果是负,需 (x%mod+mod)%mod 修正)。
排除法:其余选项是常见误解/错位结果。
C++ 的 string 存中文(UTF-8)时 s[i]?
考点:易错:字符串比较中文。
解析:见题面情境,按易错:字符串比较中文 的规则推演可得答案(正确项为 是单个字节(非完整汉字),汉字需 3 字节)。
排除法:其余选项是常见误解/错位结果。