描述
Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转变成另一个所需的最少单字符编辑操作次数。被允许的转变包括:
∙ ∙对于任意一个字符串,在任意位置插入一个字符;
∙ ∙对于任意一个字符串,删除任意一个字符;
∙ ∙对于任意一个字符串,替换任意一个字符。
现在,对于给定的字符串 ss 和 tt,请计算出它们的编辑距离。
输入描述:
第一行输入一个长度为 1≦len(s)≦1031≦len(s)≦103,仅由小写字母组成的字符串 ss。
第二行输入一个长度为 1≦len(t)≦1031≦len(t)≦103,仅由小写字母组成的字符串 tt。
输出描述:
输出一个整数,表示 ss 和 tt 的编辑距离。
输入:
abcdefg
abcdef
输出:1
说明:在这个样例中,可以选择将 ss 末尾的 'g'删除。当然,也可以选择在 tt 末尾插入 'g'。
代码
java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = in.nextLine(); // 输入字符串 s
String t = in.nextLine(); // 输入字符串 t
int x = levenshtein(s, t);
System.out.println(x);
}
/**
* 计算字符串 s 和 t 的 Levenshtein 编辑距离
* 编辑操作包括:插入、删除、替换,代价为 1
*/
public static int levenshtein(String s, String t) {
// dp[i][j] 表示 s 的前 i 个字符 与 t 的前 j 个字符 的编辑距离
int[][] dp = new int[s.length() + 1][t.length() + 1];
// 初始化第一列:s 的前 i 个字符变成空串,需要删除 i 次
for (int i = 0; i < s.length(); i++) {
dp[i + 1][0] = i + 1;
}
// 初始化第一行:空串变成 t 的前 j 个字符,需要插入 j 次
for (int i = 0; i < t.length(); i++) {
dp[0][i + 1] = i + 1;
}
// 填 DP 表
for (int i = 0; i < s.length(); i++) {
for (int j = 0; j < t.length(); j++) {
// 如果两个字符相同,不需要操作
if (s.charAt(i) == t.charAt(j)) {
dp[i + 1][j + 1] = dp[i][j];
} else {
// 否则取三种操作代价的最小值 + 1
// dp[i][j] → 替换
// dp[i+1][j] → 插入(相当于 t 多一个字符)
// dp[i][j+1] → 删除(相当于 s 少一个字符)
dp[i + 1][j + 1] =
Math.min(
Math.min(dp[i][j], dp[i + 1][j]),
dp[i][j + 1]
) + 1;
}
}
}
// dp[s.length()][t.length()] 就是最终结果
return dp[s.length()][t.length()];
}
}