【牛客网】HJ52 计算字符串的编辑距离(动态规划)

本文介绍了如何利用动态规划求解字符串A转换到字符串B的编辑距离。通过状态转移方程,分别考虑插入、删除和替换三种操作,初始化状态,并结合具体例子进行解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

https://www.nowcoder.com/practice/3959837097c7413a961a135d7104c314?tpId=37&&tqId=21275&rp=1&ru=/activity/oj&qru=/ta/huawei/question-ranking
在这里插入图片描述在这里插入图片描述

解题思路:
问题: 字符串A转换成字符串B的编辑距离
子问题: 字符串A的一部分转换成字符串B的一部分的编辑距离
状态F(i, j): 字符串A的前i个字符转换成字符串B的前j个字符的编辑距离
状态转移方程: F(i, j) = 最小{F(i, j - 1) + 1, F(i - 1, j) + 1, (A[i] == B[j] ? 0 : 1)}
初始状态: F(0, j) = j, F(i, 0) = i

F(i, j) : A[1, i] ---> B[1, j]
插入操作:
F(i, j - 1), A的前i个字符 == B的前j - 1个字符, 即 A[1, i] ---> B[1, j - 1] + 插入第j个字符
删除操作:
F(i - 1, j), A的前i - 1个字符 == B的前j个字符, 即 A[1, i - 1] ---> B[1, j] + 删除第i个字符
替换操作:
F(i - 1, j - 1), A的前i - 1个字符 == B的前j个字符, 即A[1, i - 1] ---> B[1, j + 1] + 分两种情况
两种情况如下:
A[i] == B[j] 不替换
A[i] != B[j]A的第i个字符替换成B的第j个字符

举例如下:
在这里插入图片描述

import java.io.*;
import java.util.*;
public class Main{
    public static void main(String[] args) throws Exception{
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String str1;
        while((str1 = reader.readLine()) != null){
            String str2 = reader.readLine();
            System.out.println(getDistance(str1, str2));
        }
    }
    
    public static int getDistance(String str1, String str2){
        char[] arr1 = str1.toCharArray();
        char[] arr2 = str2.toCharArray();
        int len1 = arr1.length;
        int len2 = arr2.length;
        int[][] dist = new int[len1 + 1][len2 + 1];
        //字符串B为空, 那么操作次数为字符串A的长度
        for(int i = 0; i <= len1; i++){
            dist[i][0] = i;
        }
        //字符串A为空, 那么操作次数为字符串B的长度
        for(int j = 0; j <= len2; j++){
            dist[0][j] = j;
        }
        for(int i = 1; i <= len1; i++){
            for(int j = 1; j <= len2; j++){
                //此时的操作数 = 上面两种情况操作次数的最小值 + 1
                //+ 1 指的是只能操作一次的插入 / 删除操作
                dist[i][j] = Math.min(dist[i - 1][j], dist[i][j - 1]) + 1;
                
                //考虑替换操作
                if(arr1[i - 1] == arr2[j - 1]){
                    //如果前i - 1个字符等于前j - 1个字符
                    //那么不需要进行替换操作
                    //此时的操作数 = 插入 / 删除操作和dist[i - 1][j - 1]的最小值
                    dist[i][j] = Math.min(dist[i][j], dist[i - 1][j - 1]);
                }else{
                    //如果前i - 1个字符不等于前j - 1个字符
                    //需要进行替换操作, 即dist[i - 1][j - 1] + 1
                    //此时的操作数 = 插入 / 删除操作和dist[i - 1][j - 1] + 1的最小值
                    dist[i][j] = Math.min(dist[i][j], dist[i - 1][j - 1] + 1);
                }
            }
        }
        return dist[len1][len2];
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值