再谈字符串

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

字符串取模

定义

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

运算

( 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

相关推荐
牛艺翔4 小时前
C++ 基础知识
开发语言·c++
兔兔兔兔14 小时前
记录C++ 11
开发语言·c++
码匠许师傅4 小时前
【C++ 面试真题】32. 聊聊 C++ 的原子变量与无锁编程
java·c++·面试
wabs6665 小时前
关于栈【力扣150.逆波兰表达式求值的思考】
数据结构·c++·算法·leetcode··代码随想录
欧特克_Glodon5 小时前
OpenCV计算机视觉开发入门与实践<十七>:点运算与灰度变换概述
c++·人工智能·opencv·计算机视觉
牛油果子哥q5 小时前
C++序列式容器深度精讲:vector/list/deque底层实现、扩容原理、迭代器失效、性能对比、工程选型避坑
开发语言·c++·list
啦啦啦啦啦zzzz5 小时前
升序链表的定时器
linux·服务器·网络·数据结构·c++·链表
WBluuue5 小时前
数据结构与算法:带权并查集
数据结构·c++·算法
渡我白衣5 小时前
Acceptor模块的设计与实现
java·linux·服务器·开发语言·网络·c++·人工智能
程序员AlbertTu5 小时前
M01 | 浮点数与误差:数值计算的世界观
c++·数值运算