求两个字符串的最大公共子串

在计算机科学中,找到两个字符串的最大公共子串是一个常见的问题。我们可以通过动态规划的方式来解决这个问题。下面,我将为刚入行的小白详细解释如何实现这个功能。

整体流程

为了清晰地展示整个实现过程,我们可以将其分为以下几个步骤:

步骤描述
1初始化一个二维数组
2填充二维数组
3找到最大子串的长度及结束位置
4根据最大子串的信息提取子串
5返回子串

每一步的详细实现

第一步:初始化一个二维数组

我们需要定义一个二维数组来存放字符串的比较结果。我们为两个字符串创建一个大小为 (m+1)x(n+1) 的数组,其中 m 和 n 分别是两个字符串的长度。这是因为我们需要一个额外的行和列来处理空字符串的情况。

def longest_common_substring(s1, s2):
    m, n = len(s1), len(s2)
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    max_length = 0  # 最大子串的长度
    end_pos = 0     # 最大子串结束的位置
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
第二步:填充二维数组

使用双重循环遍历两个字符串的字符,进行比较。如果字符相同,则在二维数组中相应位置加1;如果不同,则该位置为0。

    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if s1[i - 1] == s2[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1  # 如果匹配,长度加1
                if dp[i][j] > max_length:
                    max_length = dp[i][j]  # 更新最大长度
                    end_pos = i  # 更新结束的位置
            else:
                dp[i][j] = 0  # 不匹配则长度为0
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
第三步:找到最大子串的长度及结束位置

在构建过程中,我们已经在上一步更新了max_lengthend_pos。这使得我们可以在一个步骤中完成这一部分。

第四步:根据最大子串的信息提取子串

根据end_posmax_length的信息,我们可以提取到最大公共子串。

    longest_substring = s1[end_pos - max_length:end_pos]
  • 1.
第五步:返回子串

最后,我们将提取到的子串返回。

    return longest_substring
  • 1.
完整函数

将以上步骤汇总,得到完整的求最大公共子串的函数:

def longest_common_substring(s1, s2):
    m, n = len(s1), len(s2)
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    max_length = 0  # 最大子串的长度
    end_pos = 0     # 最大子串结束的位置

    for i in range(1, m + 1):
        for j in range(1, n + 1):
            if s1[i - 1] == s2[j - 1]:
                dp[i][j] = dp[i - 1][j - 1] + 1  # 如果匹配,长度加1
                if dp[i][j] > max_length:
                    max_length = dp[i][j]  # 更新最大长度
                    end_pos = i  # 更新结束的位置
            else:
                dp[i][j] = 0  # 不匹配则长度为0

    longest_substring = s1[end_pos - max_length:end_pos]
    return longest_substring
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

旅行图

我们可以用 Mermaid 语法绘制出一个简单的旅行图,展示从输入字符串到输出最大公共子串的过程。

从字符串到公共子串的旅程 到达 存储 移动
输入
输入
存储
输入字符串1
输入字符串1
存储
输入字符串2
输入字符串2
处理
处理
移动
初始化二维数组
初始化二维数组
移动
填充二维数组
填充二维数组
移动
查找最大长度与结束位置
查找最大长度与结束位置
移动
提取最大公共子串
提取最大公共子串
输出
输出
到达
返回最大公共子串
返回最大公共子串
从字符串到公共子串的旅程

状态图

我们同样可以用 Mermaid 语法展示状态图,清晰地展示每一步的状态转变:

初始化 填充 查找最大长度 提取子串

结论

通过以上步骤,我们详细讲解了如何使用Python实现求两个字符串的最大公共子串的功能。希望这篇文章能帮助你更好地理解动态规划的基本思路。同时,也鼓励你动手实现并试着扩展这个算法,比如考虑重复子串的个数,或是修改为求公共前缀等。编程的乐趣在于实践,探索出无数的可能性让我们不断成长。继续加油!