数据结构与算法之动态规划 编辑距离 字符串操作 / 状态转移 求解

数据结构与算法阿木 发布于 2025-07-12 6 次阅读


摘要:

编辑距离,也称为Levenshtein距离,是一种衡量两个字符串之间差异的指标。它通过计算将一个字符串转换成另一个字符串所需的最少编辑操作次数来衡量。编辑操作包括插入、删除和替换。本文将围绕编辑距离算法,深入探讨动态规划在字符串操作中的应用,并通过代码实现来展示这一算法的原理和技巧。

一、

编辑距离算法在自然语言处理、生物信息学、文本比较等领域有着广泛的应用。动态规划作为一种高效解决序列问题的方法,在编辑距离算法中扮演着重要角色。本文将详细介绍编辑距离算法的原理,并通过Python代码实现来展示动态规划在字符串操作中的应用。

二、编辑距离算法原理

编辑距离算法的核心思想是将两个字符串分别看作两个序列,通过插入、删除和替换操作,使得两个序列达到最小差异。算法的基本步骤如下:

1. 定义一个二维数组dp,其中dp[i][j]表示将字符串s1的前i个字符与字符串s2的前j个字符进行编辑操作后的最小编辑距离。

2. 初始化dp数组的第一行和第一列,分别表示将空字符串与s1或s2的前i个/前j个字符进行编辑操作后的最小编辑距离。

3. 遍历dp数组,根据以下规则计算dp[i][j]的值:

- 如果s1[i-1]与s2[j-1]相同,则dp[i][j] = dp[i-1][j-1];

- 如果s1[i-1]与s2[j-1]不同,则dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1]) + 1;

4. dp数组的最后一个元素dp[m][n]即为编辑距离。

三、Python代码实现

以下是一个使用Python实现的编辑距离算法示例:

python

def edit_distance(s1, s2):


m, n = len(s1), len(s2)


dp = [[0] (n + 1) for _ in range(m + 1)]

初始化dp数组的第一行和第一列


for i in range(m + 1):


dp[i][0] = i


for j in range(n + 1):


dp[0][j] = j

遍历dp数组,计算编辑距离


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]


else:


dp[i][j] = min(dp[i - 1][j - 1], dp[i - 1][j], dp[i][j - 1]) + 1

return dp[m][n]

测试


s1 = "kitten"


s2 = "sitting"


print("编辑距离:", edit_distance(s1, s2))


四、动态规划优化

在上述代码中,我们使用了二维数组dp来存储中间结果。由于dp数组的每一行只依赖于上一行的数据,因此我们可以通过一维数组来优化空间复杂度。

python

def edit_distance_optimized(s1, s2):


m, n = len(s1), len(s2)


dp = [0] (n + 1)

初始化dp数组的第一列


for i in range(m + 1):


dp[i] = i

遍历dp数组,计算编辑距离


for i in range(1, m + 1):


for j in range(1, n + 1):


if s1[i - 1] == s2[j - 1]:


dp[j] = dp[j - 1]


else:


dp[j] = min(dp[j - 1], dp[j], dp[j - 1] + 1)

return dp[n]

测试


print("优化后的编辑距离:", edit_distance_optimized(s1, s2))


五、总结

本文深入浅出地介绍了编辑距离算法的原理,并通过Python代码展示了动态规划在字符串操作中的应用。通过优化空间复杂度,我们得到了一个更加高效的算法实现。编辑距离算法在多个领域有着广泛的应用,掌握其原理和实现方法对于从事相关领域的研究和开发具有重要意义。