返回

字符串匹配算法巅峰对决:BF算法VS KMP算法

前端

在计算机科学中,字符串匹配问题是一个非常重要的基础问题,也是算法领域研究的热点之一。所谓字符串匹配问题,就是寻找模式串在主串中的位置,如果存在则返回索引,否则返回-1。

解决字符串匹配问题的算法有很多,其中最简单、最直观的算法是BF算法,也称为暴力匹配算法。BF算法的原理非常简单:从主串的第一个字符开始,依次与模式串的第一个字符比较,如果相同则继续比较下一个字符,直到模式串的最后一个字符。如果在比较过程中发现不相同,则将模式串向右移动一个字符,然后从主串的当前位置重新开始比较。

虽然BF算法的原理简单,但其效率却非常低,因为在最坏的情况下,BF算法需要比较n*m次字符,其中n是主串的长度,m是模式串的长度。因此,BF算法只适用于处理短字符串的情况。

为了提高字符串匹配的效率,人们提出了KMP算法,KMP算法是一种改进的字符串匹配算法,其原理是利用模式串本身的特点来减少不必要的比较次数。KMP算法通过预处理模式串,构建一个next数组,next数组的每个元素代表了模式串中某个字符第一次出现的位置。在匹配过程中,如果主串的某个字符与模式串的某个字符不相同,则将模式串向右移动next[j]个字符,然后从主串的当前位置重新开始比较。

KMP算法的效率要比BF算法高很多,在最坏的情况下,KMP算法只需要比较n+m次字符。因此,KMP算法非常适合处理长字符串的情况。

下面是BF算法和KMP算法的详细示例代码:

def bf(main_str, pattern):
    """
    暴力匹配算法
    :param main_str: 主串
    :param pattern: 模式串
    :return: 匹配到的索引,否则返回-1
    """
    main_len = len(main_str)
    pattern_len = len(pattern)

    for i in range(main_len - pattern_len + 1):
        flag = True
        for j in range(pattern_len):
            if main_str[i+j] != pattern[j]:
                flag = False
                break

        if flag:
            return i

    return -1


def kmp(main_str, pattern):
    """
    KMP算法
    :param main_str: 主串
    :param pattern: 模式串
    :return: 匹配到的索引,否则返回-1
    """
    def get_next(pattern):
        """
        获取next数组
        :param pattern: 模式串
        :return: next数组
        """
        pattern_len = len(pattern)
        next = [0] * pattern_len

        i = 1
        j = 0
        while i < pattern_len:
            if pattern[i] == pattern[j]:
                j += 1
                next[i] = j
                i += 1
            else:
                if j > 0:
                    j = next[j-1]
                else:
                    next[i] = 0
                    i += 1

        return next

    main_len = len(main_str)
    pattern_len = len(pattern)
    next = get_next(pattern)

    i = 0
    j = 0
    while i < main_len and j < pattern_len:
        if main_str[i] == pattern[j]:
            i += 1
            j += 1
        else:
            if j > 0:
                j = next[j-1]
            else:
                i += 1

    if j == pattern_len:
        return i - pattern_len

    return -1


if __name__ == '__main__':
    main_str = 'hello world'
    pattern = 'wor'

    print(bf(main_str, pattern))  # 输出:6
    print(kmp(main_str, pattern))  # 输出:6

以上就是字符串匹配问题中BF算法和KMP算法的详细介绍。希望本文对您有所帮助。