欢迎访问宙启技术站
智能推送

Python函数应用:寻找最长公共子串

发布时间:2023-05-30 05:18:56

最长公共子串是指两个字符串中最长的相同子串。 比如字符串“ABCD”和“EABC”,它们的最长公共子串是“ABC”。

在求解最长公共子串的问题中,我们可以使用暴力枚举、动态规划和后缀数组等不同的方法。下面,我们将介绍一种基于动态规划的方法来寻找两个字符串的最长公共子串。

动态规划求最长公共子串

假设有两个字符串S1和S2,长度分别为n和m。我们可以使用一个二维数组f来表示S1中前i个字符和S2中前j个字符的最长公共子串长度。

其中,f[i][j]表示S1中前i个字符和S2中前j个字符的最长公共子串长度。当S1[i]等于S2[j]时,有:

f[i][j] = f[i-1][j-1] + 1

否则,有:

f[i][j] = 0

最终,我们需要遍历f数组,找到其中最大的值即为最长公共子串的长度。

例如,考虑字符串S1="ABCD"和S2="EABC",它们的f数组如下所示:

E A B C

A 0 1 0 0

B 0 0 2 0

C 0 0 0 3

D 0 0 0 0

最长公共子串的长度为3,对应的子串为“ABC”。

Python 实现

下面是 Python 代码示例,实现了动态规划求解最长公共子串的过程。输入s1和s2是两个字符串,输出为它们的最长公共子串。代码中使用了一个二维数组dp来存储每个位置对应的最长公共子串长度,同时还记录了最长公共子串的长度max_len和它在s1中的结束位置end_index。

def lcs(s1, s2):
    len1, len2 = len(s1), len(s2)
    dp = [[0] * (len2 + 1) for _ in range(len1 + 1)]
    max_len, end_index = 0, 0
    for i in range(1, len1 + 1):
        for j in range(1, len2 + 1):
            if s1[i - 1] == s2[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1
                if dp[i][j] > max_len:
                    max_len = dp[i][j]
                    end_index = i
            else:
                dp[i][j] = 0
    return s1[end_index - max_len : end_index], max_len

接下来,我们给出一个示例,使用上述函数求解字符串S1="ABCD"和S2="EABC"的最长公共子串。

s1 = "ABCD"
s2 = "EABC"
print(lcs(s1, s2))  # 输出:('ABC', 3)

从上面的例子可以看出,使用动态规划可以高效地求解两个字符串的最长公共子串,时间复杂度为O(nm)。当然,也可以使用其他的算法来解决这个问题, 比如后缀数组、哈希和滑动窗口等。不同的算法适用于不同的场景,读者可以根据实际需求选择性地使用。