Java语言描述:动态规划法之编辑距离问题

本文介绍了一种使用动态规划解决编辑距离问题的方法。该算法通过逐步分解问题并利用重叠子问题性质来寻找两个字符串间的最小编辑距离。

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


/*
 * 该程序通过动态规划法解决了编辑距离问题。
 * 算法思想:
 * 将该问题逐步分解为子问题,每次让其规模降1,dist[i][j]标识出了当目标字段长为从第1个字母到
 * 第i个字母,源字段从第1个字母到第j个字母时的最短路径。所以,我们要求的目标值就是dis[des.length][res.length]。
 * 最优子结构:当该问题的所有子问题都达到最优解时,dis[des.length][res.length]一定达到最优解。
 * 重叠子问题:每一次将问题迭代进去计算时,都需要用到之前一次求出的结果,因此将每一个dis[][]的值都存在
 * dis二维数组中,以自底向上的方式递归地从子问题的最优解逐步构造出整个问题的最优解。
 * 边界条件:由题意可知,dis[0][j]的值就是源字符串的长度j,dis[i][0]就是目的字符串的长度i。
 * 递归关系式:假设我们要求dis[i][j],因此,
 * 一、当des[i]=res[j]时,dis[i][j]=dis[i-1][j-1]。
 * 二、当des[i]!=res[j]时,dis[i][j]=dis[i-1][j-1]+1.即在这种情况下对res[j]做一次修改使之等于des[i]即可。
 * 三、dis[i][j]=dis[i-1][j],直接在源字符串结尾添加一个des[i]。
 * 四、dis[i][j]=dis[i][j-1],直接将源字符串结尾的字符删除。
 * 对于以上不同的4种操作,我们通过getMin函数选择结果最小的值作为dis[i][j]的值。
 * 通过双层for循环,最终遍历整个dis[des.length][res.length].
 * 最终返回dis[des.length][res.length]就是我们要求的值。
 * (注:在本程序中,字符串转化为数组后在0的位置增加一个空格,字符从位置1开始放置,因此
 * 最后一个目的字符为des.length-1)。
 * 该程序调试完全成功:
 * 输入为:“fxpimu”和“xwrs”      输出为:5
 * */

package Dynamic;
public class getDist {
	public static void main(String[] args) throws Exception{
		//建立输入输出流来读取和写入文件信息。
		String input1 = "fxpimu";
		String input2 = "xwrs";
		int ans = getDist(input1,input2);
		System.out.println(input1+"和"+input2+"之间的距离为:"+ans);

	}
	public static int getDist(String re,String de){
		int temp1,temp2,temp3;
		//将读取到的字符串前面加上1个空格后转变为字符数组。
		char res[] = (" "+re).toCharArray();
		char des[] = (" "+de).toCharArray();
		//获取字符数组的长度。
		int Ldes = des.length;
		int Lres = res.length;
		int[][] dis = new int[Ldes][Lres];
		//对dis[][]按照算法思想中进行初始化。
		for(int i=0;i<res.length;i++)
			dis[0][i]=i;
		for(int j=0;j<des.length;j++)
			dis[j][0]=j;
		for(int i=1;i<des.length;i++)
			for(int j=1;j<res.length;j++){
				//第一种情况
				if(des[i]==res[j])
					temp1=dis[i-1][j-1];
				//第二种情况
				else
					temp1=dis[i-1][j-1]+1;
				//第三种和第四种情况
				temp2=dis[i-1][j]+1;
				temp3=dis[i][j-1]+1;
				//获取四种情况的最小值
				dis[i][j]=getMin(temp1,temp2,temp3);
			}
		return (dis[Ldes-1][Lres-1]);
	}
	//获取最小值的子程序。
	public static int getMin(int a,int b,int c){
		int min= a;
		if(b<min) min=b;
		if(c<min) min=c;
		return min;
	}
}

运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值