字符串-串匹配算法和朴素匹配算法

串匹配算法

       做字符串匹配的基础是逐个字符匹配,从串匹配的角度看,两个字符的比较只需要得到相同或者不同的结论,是一个逻辑判断。

如果从目标串的某个位置i开始,模式串里的每个字符都与目标串里的对应字符相同,就是找到了一个匹配,如果在比较中遇到了一对不同的字符,那就是不匹配,说明模式串不能与目标串中从位置i开始的子串匹配。

串匹配算法的关键两点:1.怎样选择开始比较的字符对,2.发现了不匹配之后,下一步怎么做。对这两点的不同处理策略,就形成了不同的串匹配算法。

朴素匹配算法

  最简单的皮素匹配算法采用最直观可行的策略,1.从左到右逐个字符匹配,2.发现不匹配 时,转去考虑目标串里的下一个位置是否与模式串匹配。

下面时朴素匹配算法的一个实现:

def naive_match(str1, str2):
    m, n = len(str2), len(str1)
    i, j = 0, 0
    while i < m and j < n:
        if str2[i] == str1[j]:
            i, j = i+1, j+1
        else:
            i, j = 0, j - i - 1
    # 匹配返回下标
    if i == m:
        return j - i
    return -1

  上诉串匹配算法非常简单,容易理解,但是效率非常低。下面介绍一个高效的字符串匹配算法。

无回溯串匹配算法(KMP算法)

  如上图,就是朴素匹配算法与KMP算法的匹配过程,设目标串时ababcabcacbab,模式串是abcac。图中状态(0)的匹配进行到模式串中的c时失败,此前有 两次匹配成功,从中可知目标串前两个字符与模式串前两个字符相同,由于模式串的前两个字符不同,与b匹配的目标串字符不可能与a匹配,所以状态(1)的匹配一定失败。朴素匹配算法未利用这种信息,做了无用功。再看看状态(2),这里4个字符都匹配最后匹配c失败,由于模式串第一个a与其后两个字符(bc)不同,用a去匹配目标串的b,c也一定会失败,跳过这两个位置不会丢掉匹配点,另一方面,模式串中下标为3的字符也是a,它在状态(2)匹配成功,首字符a不必重做这一匹配。朴素的匹配算法中没有考虑这些问题,总是一步步移位从头 比较。

  从实例的分析可知,由于模式串在匹配之前已知,而且通常在匹配中反复使用,如果先对模式串做一写分析,记录得到的有用的信息(如其中哪些位置的字符相同或不同),就有可能避免一些不必要的匹配,提高匹配效率。这种做法是实际匹配前的静态预处理,只需要做一次。记录下来的信息可以在匹配中反复使用。

  KMP算法的精髓就是开发了一套分析和记录模式串信息的机制(和算法),而后借助得到的信息加速匹配。

算法问题分析:

未完待续。。。。。。

posted @ 2020-07-29 22:39  你的莫  阅读(387)  评论(0)    收藏  举报