编辑距离问题——动态规划

问题描述

给定两个字符串s和t,求利用删除、插入、替换三种操作将s替换为t串的最小编辑次数,即最短编辑距离。

动态规划代码求解

import numpy
def Minimum_Edit_Distance(s, t):
	"""

    :param s: 字符串s
    :param t: 字符串t
    :return: s和t的最小编辑距离
    """
    n = len(s)
    m = len(t)
    # 新建D[0...n,0...m]和Rec[0...n,0...m]两个二维数组
    D = [[0 for i in range(m + 1)] for j in range(n + 1)]
    Rec = [[None for i in range(m + 1)] for j in range(n + 1)]
     # 初始化
    for i in range(1, n + 1):
    	D[i][0] = i
    	Rec[i][0] = "U"
    for j in range(1, m + 1):
    	D[0][j] = j
    	Rec[0][j] = "L"
    # 动态规划
    # 依次计算子问题
    for i in range(0, n):
    	for j in range(0, m):
    		# 替换/无操作
    		c = 0
    		if s[i] != t[j]:
    			c = 1
    		replace = D[i][j] + c
    		delete = D[i][j + 1] + 1
    		insert = D[i + 1][j] + 1
    		# 采取替换操作
    		if replace == min(delete, insert, replace):
    			# 记录编辑距离和操作
    			D[i + 1][j + 1] = D[i][j] + c
    			Rec[i + 1][j + 1] = "LU"
    		# 采取插入操作
    		elif insert == min(delete, insert, replace):
    			D[i + 1][j + 1] = D[i + 1][j] + 1
    			Rec[i + 1][j + 1] = "L"
    		# 采取删除操作
    		else:
    			D[i + 1][j + 1] = D[i][j + 1] + 1
    			Rec[i + 1][j + 1] = "U"
    # 最优方案追踪
    def Print_MED(Rec, s, t, i, j):
    	"""

        :param Rec: 追踪矩阵Rec
        :param s: 字符串s
        :param t: 字符串t
        :param i: 位置索引i
        :param j: 位置索引j
        :return: 操作序列
        """
    	if i < 0 and j < 0:
    		return None
    	# 采取替换操作
    	if Rec[ i + 1][j + 1] == "LU":
    		# 递归输出子问题方案
    		Print_MED(Rec, s, t, i - 1, j - 1)
    		# 替换/无操作
    		if s[i] == t[j]:
    			print("无需操作")
    		else:
    			print(f"用{t[j]}替换{s[i]}")
    	# 采取删除操作
    	elif Rec[i + 1][j + 1] == "U":
    		Print_MED(Rec, s, t, i - 1, j)
    		print(f"删除{s[i]}")
    	# 采取插入操作
    	else:
    		Print_MED(Rec, s, t, i, j - 1)
    		print(f"插入{t[j]}")
    return f"{Print_MED(Rec, s, t, i, j)}\n递推公式表:\n{numpy.asmatrix(D)}\n 追踪数组表:\n{numpy.asmatrix(Rec)}")
if __name__ == '__main__':
	s = ["A", "B", "C", "B", "D", "A", "B"]
	t = ["B", "D", "C", "A", "B", "A"]
	print(Minimum_Edit_Distance(s, t))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值