题意描述:给定任意两个字符串,写出一个算法计算它们的相似度
许多程序会大量使用字符串,对于不同的字符串,我们希望能够有办法判断其相似程度。定义下列操作方法使得两个不同的字符串变得相同:
(1)修改一个字符(如把‘a’改为‘b’);
(2)增加一个字符(如把‘abdd’变为‘aebdd’);
(3)删除一个字符(如把‘travelling’变为‘traveling’);
比如,对于‘abcdefg’和字符串‘abcdef’两个字符串来说,我们认为可以通过增加/减少一个‘g’的方式来达到目的。上面的两种方案,都仅需要一次操作。
把这个操作所需要的次数定义为两个字符串的距离,而相似度等于“距离+1”的倒数。也就是说,“abcdefg”和“abcdef”的距离为1,则相似度为1/2=0.5;
解题思路:递归解决,将大问题转化为规模较小的子问题:
(1)一步操作之后,把sA[2...LenA]和sB[1...LenB]变成相同字符串;
(2)一步操作之后,把把sA[1...LenA]和sB[2...LenB]变成相同字符串 ;
(3)一步操作之后,把把sA[2...LenA]和sB[2...LenB]变成相同字符串;
import java.util.Scanner;
public class CalculateStrDistance {
private static int calculateStrDistance(String str1, String str2) {
return calculateStrDistance(str1,0,str1.length()-1, str2,0,str2.length()-1);
}
private static int calculateStrDistance(String str1, int str1Begin, int str1End, String str2, int str2Begin, int str2End) {
if(str1Begin > str1End){
if(str2Begin > str2End)
return 0;
else
return str2End-str2Begin + 1;
}else if(str2Begin > str2End){
if(str1Begin > str1End)
return 0;
else return str1End - str1Begin + 1;
}else{
if(str1.charAt(str1Begin) == str2.charAt(str2Begin))
return calculateStrDistance(str1,str1Begin+1,str1End, str2,str2Begin+1, str2End);
else{
/*一步操作之后,把str1[2...LenA]和str2[1...LenB]变成相同字符串*/
int d1 = calculateStrDistance(str1, str1Begin, str1End, str2, str2Begin + 1, str2End);
/*一步操作之后,把把str1[1...LenA]和str2[2...LenB]变成相同字符串*/
int d2 = calculateStrDistance(str1, str1Begin + 1, str1End, str2, str2Begin, str2End);
/*一步操作之后,把把str1[2...LenA]和str2[2...LenB]变成相同字符串*/
int d3 = calculateStrDistance(str1, str1Begin + 1, str1End, str2, str2Begin + 1, str2End);
return Math.min(d1, Math.min(d2, d3)) + 1;
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String str1 = sc.next();
String str2 = sc.next();
System.out.println(calculateStrDistance(str1, str2));
}
}
}