/*
* 该程序通过动态规划法解决了编辑距离问题。
* 算法思想:
* 将该问题逐步分解为子问题,每次让其规模降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;
}
}
运行结果: