问题:给定一个源串和目标串,能够对源串进行如下操作:
在给定位置上插入一个字符
替换任意字符
删除任意字符
要求写一个程序,返回最少的操作数,使得对源串进行这些操作后等于目标串。源串和目标串的长度都小于2000。
关于编辑距离
编辑距离(Edit Distance),又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。
例如:字符串abc和字符串adbe之间的最小编辑距离是2 因为adbe删除b然后将e替换为c经过这两部
a[m]表示第一个字符串,m表示该字符串字符的下标为0~m
b[n]表示第二个字符串,n表示该字符串字符的下标为0~n
d[i][j]表示子串a[i]和子串a[j]的最小编辑距离
那么边界条件:
d[i][0]=i, 0=
d[0][j]=j, 0=
状态转移方程:d[i][j]=min{d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+lastCharCommon}
lastCharCommon=1,如果a[i-1]等于b[j-1]
lastCharCommon=0,如果a[i-1]不等于b[j-1]
下边给出java实现:
class StringEditDistance{ /*输入两个字符串,返回这两个字符串的编辑距离*/ public static int getDistance(String strA, String strB){ int distance=-1; /*输入参数合法性检查*/ if(null==strA||null==strB||strA.isEmpty()||strB.isEmpty()){ return distance; } /*两个字符串相等,编辑距离为0*/ if (strA.equals(strB)) { return 0; } System.out.println("第一个字符串:"+strA); System.out.println("第二个字符串:"+strB); int lengthA=strA.length(); int lengthB=strB.length(); int length=Math.max(lengthA,lengthB); /*申请一个二维数组,存储转移矩阵*/ int array[][]=new int[length+1][length+1]; /*边界条件初始化*/ for(int i=0;i<=length;i++){ array[i][0]=i; } /*边界条件初始化*/ for(int j=0;j<=length;j++){ array[0][j]=j; } /*状态转移方程*/ for(int i=1;i<=lengthA;i++){ for(int j=1;j<=lengthB;j++){ array[i][j]=min(array[i-1][j]+1, array[i][j-1]+1, array[i-1][j-1]+(strA.charAt(i-1)==strB.charAt(j-1)?0:1)); } } /*打印转移表格*/ System.out.println("状态转移表格:"); for(int i=0;i<=lengthA;i++){ for(int j=0;j<=lengthB;j++){ System.out.print( array[i][j]+" "); } System.out.println(); } return array[lengthA][lengthB]; } /*取三个数中的最小值*/ public static int min(int a,int b, int c){ return Math.min(Math.min(a,b),c); } }
测试用例:
String a=null; String b="abd"; System.out.println("case 1:编辑距离为:"+StringEditDistance.getDistance(a,b)); System.out.println(); a="Program"; b="P-r-o-g-r-a-m"; System.out.println("case 2:编辑距离为"+StringEditDistance.getDistance(a,b)); System.out.println(); a="2333"; b="6666666"; System.out.println("case 3:编辑距离为"+StringEditDistance.getDistance(a,b)); System.out.println(); a="adbe"; b="abc"; System.out.println("case 4:编辑距离为"+StringEditDistance.getDistance(a,b)); System.out.println(); a="hehe"; b="hehe"; System.out.println("case 5:编辑距离为"+StringEditDistance.getDistance(a,b)); System.out.println();
运行结果: