再谈字符串

今天对字符串有了一点新的理解,遂再写一篇博客。

字符串取模

定义

可以参考 我之前写的博客。不再赘述。下文用长度表示。

运算

( S + c ) ≡ ( S   m o d   P ) + c ( m o d P ) (S+c) \equiv (S \bmod P) + c \pmod P (S+c)≡(SmodP)+c(modP)

KMP

定义 g o ( i , c ) go(i, c) go(i,c) 函数,表示 P P P 的 i i i 前缀添加字符 c c c 的字符串的模 P P P 值。定义失配函数(fail) f i f_i fi 表示 P P P 的 i i i 前缀时增加的字符 c c c 失配的模 P P P 值。

g o ( i , c ) = { i + 1 P i = c g o ( f i , c ) P i ≠ c go(i, c) = \begin{cases} i+1 & P_i =c\\ go(f_i,c) & P_i \ne c \end{cases} go(i,c)={i+1go(fi,c)Pi=cPi=c

cpp 复制代码
int go(int i, char c)
{
	if(P[i] == c) return i + 1;
	if(i == 0) return 0;
	return go(f[i], c); 
}

...

for(int i=0; i<P.size(); i++)
	f[i+1] = go(f[i], c); // 这里 

fail 数组分析

关于 f i f_i fi,一方面从自动机角度考虑,即 π i \pi_i πi。

一方面从字符串取模的角度考虑, f i = P [ 1.. i ) f_i=P[1..i) fi=P[1..i) 模 P P P 值。那么 P [ 0... f i ) ≡ P [ 1... i ) ( m o d P ) P[0...f_i) \equiv P[1...i) \pmod P P[0...fi)≡P[1...i)(modP),发现 f i f_i fi 同样满足 π i \pi_i πi 的性质。

复杂度分析

对于一般的 KMP 问题,设文本串长 n n n,模式串长 m m m。

cpp 复制代码
int cur = 0;
for(int i=0; i<text.size(); i++)
{
	cur = go(cur, text[i]);
	...
}

首先有 f i < i f_i < i fi<i。文本字符可能提供当前字符串模 P P P 后的长度,至多增加 n n n 次。因此复杂度是线性的。


无限猴子类技巧

问题形如出现某个模式串 P P P 的期望长度。

由于只关心匹配,考虑只关心模 P P P 的值,据此结合待定系数法做期望 dp 即可。

例题

Censoring S

无限猴子

CTSC2006 歌唱王国


清除模式类技巧

如题,清除字符串中的模式串 P P P。

逐位枚举,考虑当前字符串模 P P P 的值即可。

例题

清除模式

Pareidolia G

相关推荐
郝学胜-神的一滴9 分钟前
C++20模板元编程 02:吃透模板基础核心四大核心知识点
开发语言·数据结构·c++·程序人生·软件工程·visual studio
代码王同学30 分钟前
2026.9.15日C++类和对象学习收获笔记
c语言·c++
刚入门的大一新生42 分钟前
Linux-简单设计libc库
linux·c++
6Hzlia1 小时前
【Classic 150 刷题计划】 LeetCode 14. 最长公共前缀 | C++ 纵向扫描法与防越界细节
c++·算法·leetcode
讳疾忌医丶10 小时前
深度拆解 RocksDB 内核:基于 C++17 的 FIFO 调度状态机与温度阶梯自愈设计
java·c++·算法·架构
2401_8685347810 小时前
OpenStack 架构全景:八个核心组件深度拆解
c++·需求分析
软件课代表CiCi11 小时前
运行库是什么?电脑缺运行库怎么办?c++运行库缺失修复全攻略
开发语言·c++·windows·电脑·dll修复·dll丢失·运行库
蒸蒸yyyyzwd12 小时前
从面经中学到的三件事
c++·笔记
时时三省12 小时前
【时时三省】计算机c语言二级考试选择题重点
c++
ThornArmor14 小时前
重铸1996|肉体渲染:关节的裂缝:分段模型积木拼装与未成熟的 RSP 矩阵骨骼动画形变
c语言·汇编·c++·python·硬件架构·游戏机