Python算法《字符串》

常规的正则及匹配等这里不赘述

看下比较高级的算法

一、KMP 算法

暴力匹配

暴力匹配方法的思想非常朴素:

依次从主串的首字符开始,与模式串逐一进行匹配;
遇到失配时,则移到主串的第二个字符,将其与模式串首字符比较,逐一进行匹配;
重复上述步骤,直至能匹配上,或剩下主串的长度不足以进行匹配。
参考代码如下:

def brute_force_match(t,p):
    tlen=len(t)
    plen=len(p)
    for i in range(tlen):
        j=0
        while t[i+j]==p[j] and j <plen:
            j=j+1
            if j==plen:
                return i
    return -1


算法复杂度分析:i 在主串上移动 (n-p)次,匹配失败时,j 移动次数最多有 p-1 次。因此复杂度为 O(n*p)。

对于暴力匹配而言,就存在重复匹配的现象。比如,第一次匹配失败时,主串,模式串失败匹配的位置的字符分别为 a 与 c ,下一次匹配时主串,模式串的起始位置分别为 T[1] 与 P[0];而在模式串中 c 之前是 ab ,未有重复结构,因此 T[1]与 P[0]肯定不能匹配上,这样造成了重复匹配。直观上,下一次匹配应从 T[2] 与 P[0] 开始。

那么如何提高匹配效率呢?那就考虑下 KMP 算法。

KMP 详细证明

KMP 算法思想归纳如下:将主串 T 的第一个字符与模式串 P 的第一个字符进行匹配。如果相等,则依次比较 T 和 P 的下一个字符。如果不相等,则 主串 T 移动(已匹配字符数-对应的部分匹配值)位,继续匹配。

关于移动位数的解释:已匹配字符数,即当前已完成匹配的字符数量。部分匹配值就是前缀和后缀的最长的共有元素的长度。

前缀指除了最后一个字符以外,一个字符串的全部头部组合。

后缀指除了第一个字符以外,一个字符串的全部尾部组合。

举个例子:以"ABCDABD"为例

"A"的前缀和后缀都为空集,共有元素的长度为 0;
"AB"的前缀为[A],后缀为[B],共有元素的长度为 0;
"ABC"的前缀为[A, AB],后缀为[BC, C],共有元素的长度 0;
"ABCD"的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为 0;
"ABCDA"的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为"A",长度为 1;
"ABCDAB"的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为"AB"࿰

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值