算法导论-第32章-字符串匹配

文章介绍了几种常见的字符串匹配算法,包括朴素算法、Rabin-Karp算法、有限自动机和Knuth-Morris-Pratt(KMP)算法。朴素算法在最坏情况下的时间复杂度为O((n-m+1)m),而Rabin-Karp算法利用滚动哈希降低了比较次数。有限自动机通过预处理构建高效匹配机制,匹配时间复杂度为Θ(n)。KMP算法通过部分匹配表避免了文本串指针回退,提高了匹配效率。

字符串匹配算法在文本文件中查找模式、DNA序列搜寻、网络引擎搜索中都有应用。

字符串匹配问题的形式化定义:假设文本是一个长为 nnn 的数组 T[1..n]T[1..n]T[1..n],而模式是一个长度为 mmm 的数组 P[1..m]P[1..m]P[1..m],其中 m≤nm \le nmn。字符数组 PPPTTT 通常称为字符串。

Figure 32.1

如果 0≤s≤n−m0 \le s \le n-m0snm,并且 T[s+1..s+m]=P[1..m]T[s+1..s+m]=P[1..m]T[s+1..s+m]=P[1..m] (即如果 T[s+j]=P[j]T[s+j]=P[j]T[s+j]=P[j],其中 1≤j≤m1 \le j \le m1jm),那么称模式 PPP 在文本 TTT 中出现,其偏移为 sss。如果 PPPTTT 中以偏移 sss 出现,则称 sss有效偏移,否则,称为无效偏移

32.1节讲解朴素字符串匹配算法,32.2节讲解Rabin-Karp算法,32.3节讲解利用优先自动机进行字符串匹配,32.4节讲解Knuth-Morris-Pratt算法。

除了朴素算法外,其他字符串匹配算法都基于模式进行了预处理,然后找到所有有效偏移,我们称第二步为“匹配”。下表给出了每个算法的预处理时间和匹配时间。每个算法的总运行时间是预处理时间和匹配时间的和

算法 预处理时间 匹配时间
朴素算法 000 O((n−m+1)m)\Omicron((n-m+1)m)O((nm+1)m)
Rabin-Karp算法 Θ(m)\Theta(m)Θ(m) O((n−m+1)m)\Omicron((n-m+1)m)O((nm+1)m)
有限自动机算法 O(m∑)\Omicron(m\sum)O(m) Θ(n)\Theta(n)Θ(n)
Knuth-Morris-Pratt Θ(m)\Theta(m)Θ(m) Θ(n)\Theta(n)Θ(n)

符号和术语

  • ∑∗\sum^* 表示包含所有有限长度的字符串集合,∑\sum 表示字母表;
  • ∣x∣|x|x 表示字符串 xxx 的长度;
  • 两个字符串 xxxyyy 的连结用 xyxyxy 表示,长度为 ∣x∣+∣y∣|x|+|y|x+y,由 xxx 的字符后接 yyy 的字符构成;
  • 字符串 www 是字符串 xxx 的前缀,记作 w⊏xw \sqsubset xwx;字符串 www 是字符串 xxx 的后缀,记作 w⊐xw \sqsupset xwx
  • 空字符串 ε\varepsilonε 是任何一个字符串的前缀和后缀。

后缀重叠引理:假设 x,yx,yx,yzzz 是满足 x⊐zx \sqsupset zxzy⊐zy \sqsupset zyz 的字符串。如果 ∣x∣≤∣y∣|x| \le |y|xy,那么 x⊐yx \sqsupset yxy;如果 ∣x∣≥∣y∣|x| \ge |y|xy,那么 y⊐xy \sqsupset xyx;如果 ∣x∣=∣y∣|x| = |y|x=y,那么 x=yx = yx=y

Figure 32.2

为了符号简单,我们把模式 P[1..m]P[1..m]P[1..m] 由前 kkk 个字符组成的前缀 P[1..k]P[1..k]P[1..k] 记作 PkP_kPk。因此 P0=ε,Pm=P=P[1..m]P_0=\varepsilon,P_m=P=P[1..m]P0=ε,Pm=P=P[1..m]

32.1 朴素字符串匹配算法

朴素字符串匹配算法是通过一个循环找到所有有效偏移,判断条件为 P[1..m]=T[s+1..s+m]P[1..m] = T[s+1..s+m]P[1..m]=T[s+1..s+m],其中 sss 总共有 n−m+1n-m+1nm+1 个可能的值。

NAIVE-STRING-MATCHER(T, P)
    n = T.length
    m = P.length
    for s = 0 to n-m
        if P[1..m] == T[s+1..s+m]
            print "Pattern occurs with shift" s

朴素字符串匹配过程可以看作“模式”沿着“文本”滑动(偏移),每次偏移都要检测模式中的字符和文本中对应的字符是否相等。

Figure 32.3

在最坏情况下,朴素字符串匹配算法运行时间为 O((n−m+1)m)\Omicron((n-m+1)m)O((nm+1)m)。偏移需要 n−m+1n-m+1nm+1 次,每次偏移,都要将模式 PPP 中的 mmm 个字符进行比较。

32.2 Rabin-Karp算法

在实际应用中,Rabin-Karp所提出的字符串匹配算法能够较好的运行, 并且还可以从中归纳出相关问题的其他算法,比如二维模式匹配。Rabin-Karp算法的预处理时间为 Θ(m)\Theta(m)Θ(m),并且在最坏情况下,它的运行时间为 Θ((n−m+1)m)\Theta((n-m+1)m)Θ((nm+1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值