设A和B是两个字符串。将字符串A转换为字符串B所用的最少字符操作数称为字符串A到字符串B的编辑距离。( 这里所说的字符操作包括:删除一个字符,插入一个字符,修改一个字符)。
private static void editMinDistance(String a, String b) {
int l1 = a.length() + 1;
int l2 = b.length() + 1;
int[][] hp = new int[l1][l2];
//
for (int i = 0; i < l1; i++) {
hp[i][0] = i;
}
for (int i = 0; i < l2; i++) {
hp[0][i] = i;
}
for (int i = 1; i < l1; i++) {
for (int j = 1; j < l2; j++) {
// 如果对应字符相等,则转换次数跟前一个字符转换次数相等
if(a.charAt(i - 1) == b.charAt(j - 1)){
hp[i][j] = hp[i - 1][j - 1];
}else {
//状态转移方程
// hp[i - 1][j]表示
hp[i][j] = Math.min(hp[i - 1][j],Math.min(hp[i][j - 1],hp[i - 1][j - 1])) + 1;
}
}
}
System.out.println(hp[a.length()][b.length()]);
}
状态转移方程:hp[i][j]。表示:字符串a中0 ~ i之间的子串转换成字符串b中0 ~ j之间的子串所需要最小的次数。
思路:
- 首先确认相关变量的初始化值。
- 确认状态转移方程。想清楚方程实际意义。
- 通过子问题推导出最终解。
- 解决重叠子问题。
解决方式:
- 暴力解决之回溯算法。
- 尝试建立平面二维数组,尝试利用初始值自下而上演化出所有情况。
- 最终状态转移方程恰恰是通过自上往下或者反推出每个二维数组中每个元素。
分析:
- 插入即将字符串B中j处字符添加至字符串A中i字符之后,此时:
// 此时B中j位置字符与A中i + 1字符相等,所以...
hp[i][j] = hp[i][j - 1] + 1
- 替换:
hp[i][j] = hp[i - 1][j - 1] + 1
- 删除:删除A中i处的字符,意味着
hp[i][j] = hp[i - 1][j] + 1