最短编辑距离和最短编辑路径

8 篇文章 0 订阅

1. 题目

求出两个字符串的最短编辑距离,及最短编辑路径。

2. 代码

# 计算两个字符串的最小编辑距离
def min_ed(source_str, target_str, source_len, target_len):
    # 初始化matrix
    matrix = []
    for i in range(source_len + 1):
        matrix.append([])
        for j in range(target_len + 1):
            matrix[i].append(0)

    # 边界条件
    for i in range(source_len + 1):
        matrix[i][0] = i
    for j in range(target_len + 1):
        matrix[0][j] = j

    # 动态规划的方法来填充matrix
    for i in range(1, source_len + 1):
        for j in range(1, target_len + 1):
            if source_str[i - 1] == target_str[j - 1]:
                matrix[i][j] = min(matrix[i - 1][j], matrix[i][j - 1], matrix[i - 1][j - 1])
            if source_str[i - 1] != target_str[j - 1]:
                matrix[i][j] = min(matrix[i - 1][j], matrix[i][j - 1], matrix[i - 1][j - 1]) + 1
    return matrix

# 列出两个字符串的最小编辑路径
def min_ed_path(path_matrix, source_str, target_str, source_len, target_len):
    # 回溯的时候相当于是在反向生成源字符串和目标字符串,所以可以在每一步打印出反向生成的源字符串和目标字符串
    source_back_str = ""
    tar_back_str = ""
    i, j = source_len, target_len
    while(i > 0 and j > 0):
        # 回溯时候的优先级 :向左 > 向上 > 向左上

        if path_matrix[i][j - 1] + 1 == path_matrix[i][j]:
            # 当path_matrix[i][j - 1] + 1 == path_matrix[i][j]时说明source_str[i - 1] == target_str[j - 2]
            # 这就是说在这个位置上source_str比target_str少一个target_str[j - 1],所以要插入一个target_str[j - 1]
            print("源字符串 插入字符 %s, 操作代价为1" % (target_str[j - 1]))
            source_back_str += target_str[j - 1]
            tar_back_str += target_str[j - 1]
            print("source back string = %s" % (source_back_str))
            print("target back string = %s" % (tar_back_str))
            j -= 1
        elif path_matrix[i - 1][j] + 1 == path_matrix[i][j]:
            # 当path_matrix[i - 1][j] + 1 == path_matrix[i][j]时说明source_str[i - 2] == target_str[j - 1]
            # 这就是说在这个位置上target_str比source_str少一个source_str[j - 1],所以source_str要删除一个source_str[j - 1]
            print("源字符串 删除字符 %s, 操作代价为1" % (source_str[i - 1]))
            print("source back string = %s" % (source_back_str))
            print("target back string = %s" % (tar_back_str))
            i -= 1
        elif path_matrix[i - 1][j - 1] + 1 == path_matrix[i][j]:
            # 当path_matrix[i - 1][j - 1] + 1 == path_matrix[i][j]时说明source_str[i - 1] != target_str[j - 1]且
            # source_str[i - 2] != target_str[j - 2]
            # 此时只能通过替换的方式来对齐
            print("源字符串 中的 %s 替换为 目标字符串 的 %s, 操作代价为1" % (source_str[i - 1], target_str[j - 1]))
            source_back_str += target_str[j - 1]
            tar_back_str += target_str[j - 1]
            print("source back string = %s" % (source_back_str))
            print("target back string = %s" % (tar_back_str))
            i -= 1
            j -= 1
        elif path_matrix[i - 1][j - 1] == path_matrix[i][j]:
            # 当path_matrix[i - 1][j - 1] + 1 == path_matrix[i][j]时说明source_str[i - 1] == target_str[j - 1]
            # 这就是说在这个位置上target_str和source_str时相同的,所以保留source_str[i - 1]和target_str[j - 1]
            print("源字符串 中的 %s 匹配 目标字符串 的 %s, 操作代价为0" % (source_str[i - 1], target_str[j - 1]))
            source_back_str += source_str[i - 1]
            tar_back_str += target_str[j - 1]
            print("source back string = %s" % (source_back_str))
            print("target back string = %s" % (tar_back_str))
            i -= 1
            j -= 1
        else:
            i -= 1
            j -= 1

def main():
    # 要注意 path_matrix[i][j]对应于source_str[i - 1]和 target_str[j - 1]
    source_str = "YPCL"
    target_str = "YCPLS"
    source_len = len(source_str)
    target_len = len(target_str)

    path_matrix = min_ed(source_str, target_str, source_len, target_len)
    min_ed_path(path_matrix, source_str, target_str, source_len, target_len)
    print("final matrix = ", path_matrix)

if __name__ == '__main__':
    main()

3. 结果

源字符串 插入字符 S, 操作代价为1
source back string = S
target back string = S
源字符串 中的 L 匹配 目标字符串 的 L, 操作代价为0
source back string = SL
target back string = SL
源字符串 插入字符 P, 操作代价为1
source back string = SLP
target back string = SLP
源字符串 中的 C 匹配 目标字符串 的 C, 操作代价为0
source back string = SLPC
target back string = SLPC
源字符串 删除字符 P, 操作代价为1
source back string = SLPC
target back string = SLPC
源字符串 中的 Y 匹配 目标字符串 的 Y, 操作代价为0
source back string = SLPCY
target back string = SLPCY
final matrix =  [[0, 1, 2, 3, 4, 5], [1, 0, 1, 2, 3, 4], [2, 1, 1, 1, 2, 3], [3, 2, 1, 2, 2, 3], [4, 3, 2, 2, 2, 3]]
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

comli_cn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值