再谈字符串

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

字符串取模

定义

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

运算

( 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

相关推荐
Want5952 小时前
C/C++跳动的爱心①
c语言·开发语言·c++
lingggggaaaa2 小时前
免杀对抗——C2远控篇&C&C++&DLL注入&过内存核晶&镂空新增&白加黑链&签名程序劫持
c语言·c++·学习·安全·网络安全·免杀对抗
phdsky3 小时前
【设计模式】建造者模式
c++·设计模式·建造者模式
H_-H3 小时前
关于const应用与const中的c++陷阱
c++
coderxiaohan3 小时前
【C++】多态
开发语言·c++
gfdhy3 小时前
【c++】哈希算法深度解析:实现、核心作用与工业级应用
c语言·开发语言·c++·算法·密码学·哈希算法·哈希
ceclar1234 小时前
C++范围操作(2)
开发语言·c++
一个不知名程序员www4 小时前
算法学习入门---vector(C++)
c++·算法
明洞日记4 小时前
【数据结构手册002】动态数组vector - 连续内存的艺术与科学
开发语言·数据结构·c++
福尔摩斯张4 小时前
《C 语言指针从入门到精通:全面笔记 + 实战习题深度解析》(超详细)
linux·运维·服务器·c语言·开发语言·c++·算法