题目:
对于不同的字符串,我们希望能够有办法判断其相似程度,我们定义了一套操作方法来把两个不相同的字符串变得相同,具体的操作办法为:
1. 修改一个字符,如把'a'替换为'b'
2. 增加一个字符,如把‘abdd'变成’aebdd'
3. 删除一个字符,如把'travelling'变成‘traveling'
两个字符串的相似度即把一个字符串变成另一个字符串的步骤的导数。
解法:
采用递归方法,逐一对比字符串,同时对字符串的操作归类为三种情况
import java.util.*;
public class StringDistance
{
public static void main(String[] args)
{
System.out.println("input Str1:");
Scanner s = new Scanner(System.in);
String s1 = s.next();
char[] c1 = new char[s1.length()];
c1 = s1.toCharArray();
System.out.println("input Str2:");
String s2 = s.next();
char[] c2 = new char[s2.length()];
c2 = s2.toCharArray();
int distance = calculateStringDistance(c1,0,s1.length()-1,c2,0,s2.length()-1);
System.out.println(s1+" and "+s2+" distance is:"+distance);
}
public static int calculateStringDistance(char[] strA,int pABegin,int pAEnd,char[] strB,int pBBegin,int pBEnd)
{
if(pABegin>pAEnd)
{
if(pBBegin>pBEnd)
return 0;
else
return pBEnd-pBBegin+1;
}
if(pBBegin>pBEnd)
{
if(pABegin>pAEnd)
return 0;
else
return pAEnd-pABegin+1;
}
if(strA[pABegin]==strB[pBBegin])
{
return calculateStringDistance(strA,pABegin+1,pAEnd,strB,pBBegin+1,pBEnd);
}
else
{
int t1 = calculateStringDistance(strA,pABegin+1,pAEnd,strB,pBBegin,pBEnd);
int t2 = calculateStringDistance(strA,pABegin,pAEnd,strB,pBBegin+1,pBEnd);
int t3 = calculateStringDistance(strA,pABegin+1,pAEnd,strB,pBBegin+1,pBEnd);
return Math.min(t1,t2)>Math.min(t2,t3)?Math.min(t1,t2)?Math.min(t2,t3);
}
}
public static int minValue(int t1, int t2, int t3)
{
int min = t1;
if(t1>t2)
{
min = t2;
if(t2>t3)
min = t3;
}
else
{
if(t1>t3)
min = t3;
}
return min;
}
}
上面的程序解决了这个问题,但是在递归过程中,有可能会出现重复计算的情况,因此下面的程序对此进行优化,即动态规划
import java.util.*;
public class StringDistanceUpdate
{
public static void main(String[] args)
{
System.out.println("input strA:");
Scanner s = new Scanner(System.in);
String strA = s.next();
System.out.println("input strB:");
String strB = s.next();
int i = 0;
i = EditDistance(strA,strB);
System.out.println(strA+" and "+strB+" distance is:"+i);
}
public static int EditDistance(String source,String target)
{
char[] s = source.toCharArray();
char[] t = target.toCharArray();
int slen = source.length();
int tlen = target.length();
int[][] d = new int[slen+1][tlen+1];
for(int i=0;i<slen;i++)
d[i][0] = i;
for(int i=0;i<tlen;i++)
d[0][i] = i;
for(int i=1;i<=slen;i++)
{
for(int j=1;j<=tlen;j++)
{
if(s[i-1]==t[j-1])
{
d[i][j] = d[i-1][j-1];
}
else
{
int insert = d[i][j-1]+1;
int del = d[i-1][j]+1;
int update = d[i-1][j-1]+1;
d[i][j] = Math.min(insert,del)>Math.min(del,update)?Math.min(insert,del):Math.min(del,update);
}
}
}
return d[slen][tlen];
}
}