FFT处理字符串匹配问题

本文介绍了如何使用FFT(快速傅里叶变换)处理字符串匹配问题,包括如何构造函数P(x)并转换为卷积形式,以及如何应用FFT解决带有通配符的字符串匹配题目。通过举例说明洛谷P4173和codeforces 528D两道题目,阐述了处理过程和关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现在我们拥有一个文本串B一个模式串A,询问A在B中出现的次数
很显然这是一个KMP的裸题,但是现在不考虑使用KMP,使用FFT来找A在B中出现的次数

首先定义函数

P(x)=∑i=0m−1(A(i)−B(x−m+i+1))P(x)=\sum_{i=0}^{m-1}(A(i)-B(x-m+i+1))P(x)=i=0m1(A(i)B(xm+i+1))

这个函数代表,字符串A在B中匹配以x为最终位置的时候的价值,我们可以看到如果m个字符都匹配上了,那么P(x)=0P(x)=0P(x)=0,因此我们需要快速求出 P(x)P(x)P(x),我们做一下化简

P(x)=∑i=0m−1(A(i)−B(x−m+i+1))2=∑i=0m−1(A2(i)+B2(x−m+i+1)−A(i)∗B(x−m+i+1))=∑i=0m−1A2(i)+∑i=0m−1B2(x−m+i+1)−∑i=0m−1A(i)∗B(x−m+i+1)P(x)=\sum_{i=0}^{m-1}(A(i)-B(x-m+i+1))^2 \\ = \sum_{i=0}^{m-1}(A^2(i)+B^2(x-m+i+1) - A(i) * B(x-m+i+1)) \\ =\sum_{i=0}^{m-1}A^2(i)+\sum_{i=0}^{m-1}B^2(x-m+i+1) - \sum_{i=0}^{m-1}A(i) * B(x-m+i+1) P(x)=i=0m1(A(i)B(xm+i+1))2=i=0m1(A2(i)+B2(xm+i+1)A(i)B(xm+i+1))=i=0m1A2(i)+i=0m1B2(xm+i+1)i=0m1A(i)B(xm+i+1)

前面两项很明显就是前缀和处理即可,但是对于最后的一项,我们要给他转化成卷积的形式,这样才可以方便使用FFT去求解,我们不妨考虑将字符串A逆转,得到字符串S,再将S替换掉公式中的A得到‘

P(x)=∑i=0m−1S2(m−i−1)+∑i=0m−1B2(x−m+i+1)−∑i=0m−1S(m−i−1)∗B(x−m+i+1)P(x)=\sum_{i=0}^{m-1}S^2(m-i-1)+\sum_{i=0}^{m-1}B^2(x-m+i+1) - \sum_{i=0}^{m-1}S(m-i-1) * B(x-m+i+1)P(x)=i=0m1S2(mi1)+i=0m1B2(xm+i+1)i=0m1S(m

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值