题目
lintcode 题目链接 http://www.lintcode.com/zh-cn/problem/edit-distance/
给出两个单词 word1 和 word2, 计算出将 word1 转换为 word2 的最少操作次数.
你总共三种操作方法:
插入一个字符
删除一个字符
替换一个字符
解析
插入一个字符为进行了一次操作, 如: fat->fait;
删除一个字符也视为进行一次操作, 如: haven->have;
替换字符也视为进行一次操作, 如: let->lit.
这个算法的原理不太好理解, 但放到矩阵中实现的过程很简单, 我们把两个字符串放到矩阵里进行解析, 这里用到了动态规划:
在相同位置上两个字符串不同: cost=1; 反则为 0
matrix[m][n]=Math.min(matrix[m-1][n]+1,matrix[m][n-1]+1,matrix[m-1][n-1]+cost)
其中 matrix[m-1][n]+1 代表删除操作, matrix[m][n-1]+1 代表新增,
matrix[m-1][n-1]+cost
代表字符的替换, 然后求出他们三个值的最小值.
图解
我们举个例子, 看下图解:
计算 ivan1 和 ivan2 两个字符串的最小操作次数:
1. 矩阵初始化
先构建一个首行首列都从 0 增长的矩阵, 长度为
- (s1.length+1)*(s2.length+1)
- .
矩阵初始化
2. 计算最小值
之后开始对比两个字符串的每个位置, 按照上一节的公式取最小值.
计算最小值
3. 类推完成, 取右下角的值, 即为最短编辑距离
类推完成
代码
- function minDistance(s1, s2) {
- const len1 = s1.length
- const len2 = s2.length
- let matrix = []
- for (let i = 0; i <= len1; i++) {
- // 构造二维数组
- matrix[i] = new Array()
- for (let j = 0; j <= len2; j++) {
- // 初始化
- if (i == 0) {
- matrix[i][j] = j
- } else if (j == 0) {
- matrix[i][j] = i
- } else {
- // 进行最小值分析
- let cost = 0
- if (s1[i - 1] != s2[j - 1]) { // 相同为 0, 不同置 1
- cost = 1
- }
- const temp = matrix[i - 1][j - 1] + cost
- matrix[i][j] = Math.min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1, temp)
- }
- }
- }
- return matrix[len1][len2] // 返回右下角的值
- }
- minDistance('jary','jerry') // 2
参考文档
编辑距离算法 (Edit Distance) https://blog.csdn.net/chichoxian/article/details/53944188
来源: http://www.jianshu.com/p/90af98493661