Python字符串匹配算法KMP实例

  • Post category:Python

下面是详细讲解“Python字符串匹配算法KMP实例”的完整攻略。

KMP算法

KMP算法是一种字符串匹配算法,用于在一个文本串S内查找一个模式串P的出现位置。该算法的核心思想是利用已经匹配过的信息,尽量减少模式串与文本串的匹配次数,从而提高匹配效率。

下面是一个Python实现KMP算法的示例:

def kmp_search(text, pattern):
    n = len(text)
    m = len(pattern)
    if m == 0:
        return 0
    if n < m:
        return -1
    lps = [] * m
    j = 0
    compute_lps(pattern, m, lps)
    i = 0
    while i < n:
        if pattern[j] == text[i]:
            i += 1
            j += 1
        if j == m:
            return i - j
        elif i < n and pattern[j] != text[i]:
            if j != 0:
                j = lps[j-1]
            else:
                i += 1
    return -1

def compute_lps(pattern, m, lps):
    len = 0
    lps[0] = 0
    i = 1
    while i < m:
        if pattern[i] == pattern[len]:
            len += 1
            lps[i] = len
            i += 1
        else:
            if len != 0:
                len = lps[len-1]
            else:
                lps[i] = 0
                i += 1

上述代码中,首先定义了一个kmp_search函数,该函数接受一个文本串和一个模式串返回模式串在文本串中的出现位置。

接着,定义了一个compute_lps函数,该函数用于计算模式串的最长共前后缀(Longest Prefix Suffix,LPS)。

然后,初始化变量n和m,分别表示文本串和模式串的长度。

接着,判断模式串是否为空,如果为空,则返回0;如果文本串长度小于模式串长度,则返回-1。

然后,初始化变量lps,用于存储模式串的LPS。

接着,调用compute_lps函数计算模式串的LPS。

然后,初始化变量i和j,分别表示文本串和模式串的当前位置。

接着,使用while循环遍历文本串,如果当前字符匹配,则i和j分别加1;如果不匹配,则j更新为lps[j-1]。

最后,如果j等于模式串的长度,则说明模式串在文本串中出现,返回i – j;否则,返回-1。

KMP算法的优化

KMP算法的效率受到模式串的LPS的影响。为了提高算法的效率,可以使用优化的LPS计算方法,如Z算法、扩展KMP算法等。

下面是一个使用Z算法优化KMP算法的Python示例:

def z_algorithm(text, pattern):
    s = pattern + '$' + text
    n = len(s)
    z = [0] * n
    l, r = 0, 0
    for i in range(1, n):
        if i > r:
            l, r = i, i
            while r < and s[r-l] == s[r]:
                r += 1
            z[i] = r - l
            r -= 1
        else:
            k = i - l
            if z[k] < r - i + 1:
                z[i] = z[k]
            else:
                l = i
                while r < n and s[r-l] == s[r]:
                    r += 1
                z[i] = r - l
                r -= 1
    return z

def kmp_search(text, pattern):
    n = len(text)
    m = len(pattern)
    if m == 0:
        return 0
    if n < m:
        return -1
    z = z_algorithm(text, pattern)
    for i in range(m+1, n+1):
        if z[i] == m:
            return i - m - 1
    return -1

上述代码中,首先定义了一个z_algorithm函数,该函数接受一个文本串和一个模式串,返回Z数组。

然后,定义了一个kmp_search函数,该函数接受一个文本串和一个模式,返回模式串在文本串中的出现位置。

接着,将模式串和文本串拼接起来,中间加上一个特字符,用于计算Z数组。

然后,初始化变量n和m,分别表示文本串和模式串的长度。

接着,判断模式串是否为空,如果为空,则返回0;如果文本串长度小于模串长度,则返回-1。

然后,调用z_algorithm函数计算Z数组。

接着,使用for循环遍历Z数组,如果Z数组中的个元素等于模式串的长度,则说明模式串在文本串中出现,返回该位置减去模式串的长度。

最后,如果没有找到模式串,则返回-1。

示例

下面是一个使用KMP算法查找模式串在文本串中出现位置的Python示例:

text = 'ABABDABACDABABCABAB'
pattern = 'ABABCABAB'
result = kmp_search(text, pattern)
if result == -1:
    print('Pattern not found in text')
else:
    print('Pattern found at index', result)

上述代码中,首先定义了一个文本串text和一个模式串pattern。

然后,调用kmp_search函数查找模式串在文本串中的出现位置。

最后,如果模式串未在文本串中出现,则输出“Pattern not found in text”;否则,输出“Pattern found at index”和模式串在文本串中的位置。

下面是一个使用Z算法优化KMP算法查找模式串在文本串中出现位置的Python示例:

text = 'ABABDABACDABABCABAB'
pattern = 'ABABCABAB'
result = kmp_search(text, pattern)
if result == -1:
    print('Pattern not found in text')
else:
    print('Pattern found at index', result)

上述代码中,首先定义了一个文本串text和一个模式串pattern。

然后,调用kmp_search函数查找模式串在文本串中的出现位置。

最后,如果模式串未在文本串中出现,则输出“Pattern not found in text”;否则,输出“Pattern found at index”和模式串在文本串中的位置。

总结

KMP算法是一种常用的字符串匹配算法,用于在一个文本串中查找一个模式串的现位置。Python中可以使用Z算法等优化方法来提高KMP算法的效率。在实现过程中,需要计算模式的LPS或Z数组,然后使用while循环或for循环遍历文本串,查找模式串的出现位置。