📜  字符串查找 (1)

📅  最后修改于: 2023-12-03 15:25:03.361000             🧑  作者: Mango

字符串查找

简介

字符串查找是指在一个字符串(目标串)中查找是否包含一个子串(模式串)的过程。字符串查找是计算机科学中常见的问题,应用广泛。在软件开发中,字符串查找设计是一个常见的任务,并且在算法和数据结构中有专门研究。

常见的字符串查找算法
1.暴力查找算法

暴力查找算法也称为朴素的字符串匹配算法,其思想是直接比较目标串中从每个位置开始的长度等于模式串长度的子串与模式串是否相等,时间复杂度为O(m*n),其中m和n分别为目标串和模式串长度。

示例代码:

def search(target, pattern):
    n = len(target)
    m = len(pattern)
    for i in range(n - m + 1):
        j = 0
        while j < m:
            if target[i + j] != pattern[j]:
                break
            j += 1
        if j == m:
            return i
    return -1
2.KMP算法

KMP算法(Knuth-Morris-Pratt算法)是一种改进的字符串匹配算法,其核心思想是利用已知信息避免无效的字符串比较操作。KMP算法中主要使用两个数组next和prefix,next数组表示当前位置之前的前缀字符串的最长相同前缀后缀长度,prefix数组表示模式串中每个位置前面的所有字符组成的字符串的最长相同前缀后缀长度。

示例代码:

def get_next(pattern):
    n = len(pattern)
    next = [-1] * n
    j = -1
    for i in range(1, n):
        while j >= 0 and pattern[i] != pattern[j + 1]:
            j = next[j]
        if pattern[i] == pattern[j + 1]:
            j += 1
        next[i] = j
    return next

def search(target, pattern):
    n = len(target)
    m = len(pattern)
    next = get_next(pattern)
    j = -1
    for i in range(n):
        while j >= 0 and target[i] != pattern[j + 1]:
            j = next[j]
        if target[i] == pattern[j + 1]:
            j += 1
        if j == m - 1:
            return i - j
    return -1
3.Boyer-Moore算法

Boyer-Moore算法是一种基于启发式的字符串匹配算法,其核心思想是倒序查找模式串中的字符,如果匹配失败,则将模式串移动尽可能多的距离,以减少比较次数。Boyer-Moore算法的时间复杂度不会超过O(m+n)。

示例代码:

def get_bc(pattern):
    m = len(pattern)
    bc = [-1] * 256
    for i in range(m):
        bc[ord(pattern[i])] = i
    return bc

def get_gs(pattern):
    m = len(pattern)
    suffix = [-1] * m
    prefix = [False] * m
    gs = [-1] * m
    for i in range(m - 1):
        j = i
        k = 0
        while j >= 0 and pattern[j] == pattern[m - 1 - k]:
            j -= 1
            k += 1
            suffix[k] = j + 1
        if j == -1:
            prefix[k] = True
        gs[i] = k
    j = 0
    for i in range(m):
        if prefix[m - 1 - i]:
            while j < m - 1 - i:
                if gs[j] == -1:
                    gs[j] = m - 1 - i
                j += 1
    for i in range(m - 1):
        gs[i] = gs[i + 1]
    return gs

def search(target, pattern):
    n = len(target)
    m = len(pattern)
    bc = get_bc(pattern)
    gs = get_gs(pattern)
    j = 0
    while j <= n - m:
        i = m - 1
        while i >= 0 and target[i + j] == pattern[i]:
            i -= 1
        if i < 0:
            return j
        x = i - bc[ord(target[i + j])]
        y = 0
        if i < m - 1:
            y = gs[i + 1]
        j += max(x, y)
    return -1
总结

以上是常见的三种字符串查找算法,每种算法都有其独特的优势和适用场景,应根据实际情况选择合适的算法。在实际开发中,应优先使用现成的字符串库和函数,以减少开发工作量,提高代码质量和性能。