We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
在写 snabbdom 复刻版的时候,发现里面有个很有趣的东西,就是在做移动节点的这个操作的时候并不是真正的去把节点移动了,而是通过插入节点,然后再把新的节点删掉。这个做法让想起了一个求最小编辑距离的问题。再 virtual dom 的节点更新就可以抽象成为一个求最小编辑距离的问题。那么这个问题具体是怎么样的,它对应的解法有具体是怎么样的,接下来就来具体看看。
1、问题
给定 2 个字符串 a, b. 编辑距离是将 a 转换为 b 的最少操作次数,操作只允许如下 3 种:
插入一个字符,例如:xy -> xzy 删除一个字符,例如:xzy -> xy 替换一个字符,例如:xzy -> xwy
上面的求 a 转换为 b 的最少操作次数 就是所谓的最小编辑距离问题。
2、� 解法
递归的本质就是用分治的思想将大的问题分成若干类似的小问题去解决。
假设字符串 a, 共 m 位,从 a[1] 到 a[m] 字符串 b, 共 m 位,从 b[1] 到 b[n] d[m][n] 表示字符串 a[1]-a[m] 转换为 b[1]-b[n] 的编辑距离
看到上面的说法就可以转化成下面的递归规律:
1、当 a[m] === b[n]的时候
2、当 a[m] !== b[n]的时候,又可以分成下面三种情况了:
3、边界条件
代码实现:
function recursion(a, b, m, n) { if (m === 0) { return n } else if (n === 0) { return m } else { let d1 = recursion(a, b, m - 1, n) + 1 let d2 = recursion(a, b, m, n - 1) + 1 let d3 = recursion(a, b, m - 1, n - 1) + 1 return Math.min(d1, d2, d3) } }
上面的递归的解法是从后面到前面的解法,比如我想知道 d[m][n],那么我可能就必须要知道 d[m-1][n-1],依次类推。那么动态规划就是从前到后面的解法。就是我先知道了若干字问题了,那么我根据这些子问题可以求到对应的原问题。举个 🌰:
我知道了 d[0][0] d[0][1] d[1][0] 那么我是可以求到 d[1][1]的:
然后可以依次求的 d[1][2]、d[1][3]、......�、d[2][1]、d[2][2]、......、� 一直到 d[m][n]为止
function dynamicDistance(a, b) { let lenA = a.length let lenB = b.length let d = [] d[0] = [] for (let j = 0; j <= lenB; j++) { d[0].push(j) } for (let i = 0; i <= lenA; i++) { if (d[i]) { d[i][0] = i } else { d[i] = [] d[i][0] = i } } for (let i = 1; i <= lenA; i++) { for (let j = 1; j <= lenB; j++) { if (a[i - 1] === b[j - 1]) { d[i][j] = d[i - 1][j - 1] } else { let m1 = d[i - 1][j] + 1 let m2 = d[i][j - 1] + 1 let m3 = d[i - 1][j - 1] + 1 d[i][j] = Math.min(m1, m2, m3) } } } return d[lenA][lenB] }
感谢:
1、编辑距离 2、最小编辑距离问题:递归与动态规划 3、动态规划求编辑距离
The text was updated successfully, but these errors were encountered:
No branches or pull requests
开始
在写 snabbdom 复刻版的时候,发现里面有个很有趣的东西,就是在做移动节点的这个操作的时候并不是真正的去把节点移动了,而是通过插入节点,然后再把新的节点删掉。这个做法让想起了一个求最小编辑距离的问题。再 virtual dom 的节点更新就可以抽象成为一个求最小编辑距离的问题。那么这个问题具体是怎么样的,它对应的解法有具体是怎么样的,接下来就来具体看看。
正文
给定 2 个字符串 a, b. 编辑距离是将 a 转换为 b 的最少操作次数,操作只允许如下 3 种:
插入一个字符,例如:xy -> xzy
删除一个字符,例如:xzy -> xy
替换一个字符,例如:xzy -> xwy
上面的求 a 转换为 b 的最少操作次数 就是所谓的最小编辑距离问题。
递归
递归的本质就是用分治的思想将大的问题分成若干类似的小问题去解决。
假设字符串 a, 共 m 位,从 a[1] 到 a[m]
字符串 b, 共 m 位,从 b[1] 到 b[n]
d[m][n] 表示字符串 a[1]-a[m] 转换为 b[1]-b[n] 的编辑距离
看到上面的说法就可以转化成下面的递归规律:
1、当 a[m] === b[n]的时候
2、当 a[m] !== b[n]的时候,又可以分成下面三种情况了:
3、边界条件
代码实现:
动态规划
上面的递归的解法是从后面到前面的解法,比如我想知道 d[m][n],那么我可能就必须要知道 d[m-1][n-1],依次类推。那么动态规划就是从前到后面的解法。就是我先知道了若干字问题了,那么我根据这些子问题可以求到对应的原问题。举个 🌰:
我知道了 d[0][0] d[0][1] d[1][0] 那么我是可以求到 d[1][1]的:
然后可以依次求的 d[1][2]、d[1][3]、......�、d[2][1]、d[2][2]、......、� 一直到 d[m][n]为止
代码实现:
最后
感谢:
1、编辑距离
2、最小编辑距离问题:递归与动态规划
3、动态规划求编辑距离
The text was updated successfully, but these errors were encountered: