• 字符串匹配算法


    一. 简单的直接算法

    比较次数:(n-m-1)*m次

    时间复杂度O(mn)

    二. Rabin-karp算法

    • 算法思想:将字符串转化成数字进行粗比较,筛选后进行细比较
    • 算法设计:

    (1)直接数值比较

        • 算法思想:字符集与 1-n 的数值满足双射,字符串转化为n进制数值
        • 优化程度:a. 比较次数:n-m次。

                                                    b. 计算次数:1 + n-m 次

        • 问题:m位数的计算复杂,优化程度低

    (2)hash函数数值比较

        • 算法思想:将较大的数值用hash函数映射到较小的数
        • 优化方法(假设n=10):

     

    预处理:fp = p[ m-1 ] + 10*(p[ m-2 ] + …+ 10*(p[ 1 ] + 10*p[ 0 ] ))) mod q。

    移位重新计算:

        • 复杂度分析:当q是素数时,平均:O(n+m),最坏:O(mn)

    三.BM算法

    1. 算法思想:

    (1)从后往前匹配的好处:在比较过程中不匹配的概率远远大于匹配的概率,基于这一特点,在匹配失败时,从后往前匹配的跳跃位置更大

    (2)每次发生不匹配,根据好后缀规则和坏字符规则(规则都是对模式串而言的)跳转到下一次比较的位置

    2. 算法设计

    (1)预处理:(对模式串T进行预处理)P[ 0-n ]

             坏字符规则:后移位数 = 失配位置 - 模式串上一次出现坏字符的位置(未出现记为 -1)

             好后缀规则:后移位数 =  好后缀的位置 - 模式串上一次出现好后缀的位置(未出现记为 -1)

    (2)从左到右移动,从后往前比较,失配时移动位置 = max{ 坏字符规则 , 好后缀规则}

    四. BMH算法

    1. 算法思想:

    总体上是BM算法的改进,关注点在模式串的最后一个字符,规则更简单

    2. 算法设计

    (1)预处理(对字符集/文本串预处理)

    偏移表:P[ 0-m-1 ]

    (2)从左到右移动,从后往前比较

    五. KMP算法---最坏情况依旧是线性

    1. 算法思想:

    文本中的每个字符仅匹配一次,充分利用已经匹配的部分做跳转

    2. 算法设计

    (1)计算最长公共前后缀:maxL

    关于如何计算最长公共前后缀(例如P=abaabcac):

    A.暴力算法:

    得到所有前缀和后缀,分别比较。

    B. 递推算法:

    得到P的所有前缀,第一个前缀的maxL初始化为0。

    假设已经求得第 i 个前缀的maxLi = k , 求解第 i + 1 个前缀的maxL(i+1)

    若 P[ k ] == P[ i ],maxL(i+1)= k+1;

    否则,使用暴力算法计算maxL.

    例:

    a  0

    ab  0  递推

    aba   1  递推

    abaa   1  递推

    abaab   2  递推(举例1)

    abaabc   0  暴力(举例2)

    abaabca   1  递推

    abaabcac   0  暴力

    maxL = { 0、0、1、1、2、0、1、0}

    (举例1)第四前缀abaa:maxL = 1,又P[ 1 ]==P[ 4 ] == b,则第五前缀abaab:maxL = 2

    (举例2)此时不满足P[ k ] == P[ i ],暴力求解,

    得到abaabc的所有前缀和所有后缀,对应比较

    abaabcabaabc

    a                   c  0

    ab                bc  0

    aba            abc  0

    abaa        aabc  0

    abaab    baabc  0

    则第六前缀abaabc:maxL = 0

    (2).将maxlL整体右移一位,初始为 -1,得到next数组

    next = { -1、0、0、1、1、2、0、1}

    (3)从左到右,从前往后匹配,失配时,将 next数组对应的值作为下标与失配位置对齐(j = next[ j ])

             

     

  • 相关阅读:
    可恶的Desktop_1.ini 规格严格
    BoundChecker 规格严格
    MySQL NetFlow Analysiser 忘记密码(转载) 规格严格
    Oracle 基本查询 规格严格
    NAN 规格严格
    面试题:为什么java不允许 super.super.xxx 这样的语句?
    国人眼中的Scrum
    NetBeans 时事通讯(刊号 # 1 Apr 02, 2008)
    面试题:为什么java不允许 super.super.xxx 这样的语句?
    快来测试你的脑年龄
  • 原文地址:https://www.cnblogs.com/duanshuai/p/13192219.html
Copyright © 2020-2023  润新知