1 | DNA 是由 ACGT 四种核苷酸组成,例如 AAAGTCTGAC,假定自然环境下 DNA 发生异变的情况有: |
动态规划
自顶向下的动态规划的思路是:选择最后一个字符,
- 如果两个字符串的第$i$,$j$个字符相同,继续判断第两个字符串的$i-1$,$j-1$的字符,即$dp[i][j]=dp[i-1][j-1]$
- 如果两个字符串的第$i$,$j$个字符相同,则继续判断第$i-1$,$j$个字符或者第$i$,$j-1$个字符
$\mathrm{d}[\mathrm{i}, \mathrm{j}] \rightarrow\left{\begin{array}{ll}
0 & \mathrm{i}=0, \mathrm{j}=0 \
\mathrm{j} & \mathrm{i}=0, \mathrm{j}>0 \
\mathrm{i} & \mathrm{j}>0, \mathrm{i}=0 \
\mathrm{d}[\mathrm{i}-1, \mathrm{j}-1] & \mathrm{S}_1(\mathrm{i})=\mathrm{S}_2(\mathrm{j}) \
\min (\mathrm{d}[\mathrm{i}, \mathrm{j}-1]+1, \mathrm{d}[\mathrm{i}-1, \mathrm{j}]+1, \mathrm{d}[\mathrm{i}-1, \mathrm{j}-1]+1) & \mathrm{S}_1(\mathrm{i}) \neq \mathrm{S}_2(\mathrm{j})
\end{array}\right.$
分析
定义:$S_1$、$S_2$表示两个字符串,$S_1(i)$表示$S_1$的第一个字符,$d[i, j]$表示$S_1$的第$i$个前缀到$S_2$的第$j$个前缀(例如:$S_1 = ”abc”,S_2 = ”def”$,求解$S_1$到$S_2$的编辑距离为$d[3, 3]$)。
若$S_1 = ”abc”, S_2 = ”dec”$,此时它们的编辑距离为$d[3, 3] = 2$,观察两个字符串的最后一个字符是相同的,也就是说$S_1(3) = S_2(3)$不需要做任何变换,故$S_1 = ”abc”, S_2 = ”dec”$ <=>$S_1’ = ”ab”, S_2’ = ”de”$,即当$S_1[i] = S[j]$时,$d[i, j] = d[i-1,j -1]$。得到公式:$d[i, j] = d[i - 1, j - 1] (S_1[i] = S_2[j])$
上面一条得出了当$S_1[i] = S_2[j]$的计算公式,显然还有另一种情况就是$S_1[i] ≠ S_2[j]$,$若S_1 = ”abc”, S_2 = ”def”$。$S_1$变换到$S_2$的过程可以“修改”,但还可以通过“插入”、“删除”使得$S_1$变换为$S_2$。
在$S_1$字符串末位插入字符$“f”$,此时$S_1 = ”abcf”,S_2 = ”def”$,此时即$S_1[i] = S_2[j]$的情况,$S_1$变换为$S_2$的编辑距离为$d[4, 3] = d[3, 2]$。所以得出$d[i, j]=d[i, j - 1] + 1$。($+1$是因为$S_1$新增了$”f”$)
在$S_2$字符串末位插入字符$“c”$,此时$S_1 = ”abc”,S_2 = ”defc”$,此时即$S_1[i] = S[j]$的情况,$S_1$变换为$S_2$的编辑距离为$d[3, 4] = d[2, 3]$。所以得出$d[i, j]=d[i - 1, j] + 1$,实际上这是对$S_1$做了删除。($+1$是因为$S_2$新增了$”c”)$
将$S_1$字符串末位字符修改为$”f”$,此时$S_1 = ”abf”,S_2 = ”def”$,此时即$S_1[i] = S[j]$的情况,$S_1$变换为$S_2$的编辑距离为$d[3, 3] = d[2, 2]$。所以得出$d[i, j] = d[i – 1, j - 1] + 1$。($+1$是因为$S_1$修改了$“c”$)
1 | import java.util.Scanner; |
参考文献