【编程-算法】2019-10-09 编辑距离Edit-distance

0 问题介绍

给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 。
你可以对一个单词进行如下三种操作:

  • 插入一个字符(insertion)
  • 删除一个字符(deletion)
  • 替换一个字符(Substitution)
    例如
    w1="kitty", 2="puittys". w1->w2的编辑距离如下
  1. kitty->pitty,替换k->s
  2. pitty->puitty ,插入u
    3.puitty->puittys,插入s
    所以->的编辑距离为3.

1 数学解答

我们定义两个字符串和,它们的长度分别是,->的编辑距离为. 其中i和j分别表示w1和w2中前个和前个字符串截取,那么和的编辑距离可以用以下数学公式描述:
Edis_{w_1,w_2}(i,j)=\begin{cases} max(i,j) \qquad \qquad \qquad \qquad \qquad \qquad \qquad \qquad \quad \qquad ,if\;min(i,j)=0\\ min\begin{cases} Edis(i-1,j)+1,\\ Edis(i,j-1)+1\\ Edis(i-1,j-1)+1,while \, w_1[i]≠w_2[j] \\ Edis(i-1,j-1)+0, while \, w_1[i]=w_2[j]\\ \end{cases} \quad ,otherwise \end{cases}
对于该数学公式描述如下:
1.表示的是字符串和中前个字符和前个字符的编辑距离,字符串的下标index从0开始。我们求得最后的编辑距离时
2.当时,证明我们截取的(记作)存在空串,此时的编辑距离就是,也就是插入或删除内的所有内容。
3.当时,为以下三个值中的最小值:
-,删除.
-,在的位置插入.
-,替换为.
-,.
4.为了控制最后的的变化,增加辅助函数

通过分析,我们很容易就发现这个算法也是由多个重叠的子问题构成的,所以我们要计划使用递归和动态规划两种算法对该问题进行解决。

2 实例演示

"",=""

/ 0a 1b 2c
0a
1d
2c
3t

步骤1:初始化第一行第一列
依照公式

/ 0a 1b 2c
0 1 2 3
0a 1
1d 2
2c 3
3t 4

步骤2:依照公式完全矩阵

/ 0a 1b 2c
0 1 2 3
0a 1 0 1 2
1d 2 1 1 2
2c 3 2 2 1
3t 4 3 3 2

3 代码实现(PHP)

3.1 递归实现

class Solution {

    /**
     * @param String $word1
     * @param String $word2
     * @return Integer
     */
    function minDistance($word1, $word2) {
        if (strlen($word1)==0)
            return strlen($word2);
        else if (strlen($word2)==0)
            return strlen($word1);
        else if ($word1==$word2)
            return 0;
        
        if ($word1[strlen($word1)-1]==$word2[strlen($word2)-1])
            $d=0;
        else 
            $d=1;
        
        return min($this->minDistance(substr($word1,0,strlen($word1)-1),$word2)+1,
                   $this->minDistance($word1,substr($word2,0,strlen($word2)-1))+1,
                  $this->minDistance(substr($word1,0,strlen($word1)-1),substr($word2,0,strlen($word2)-1))+$d);
    }
}
class Solution {

    /**
     * @param String $word1
     * @param String $word2
     * @return Integer
     */
    function minDistance($word1, $word2) {
        $LenOfWord1=strlen($word1);
        $LenOfWord2=strlen($word2);
        if ($LenOfWord1==0)
            return $LenOfWord2;
        else if ($LenOfWord2==0)
            return $LenOfWord1;
        else if ($word1==$word2)
            return 0;
        
        if ($word1[$LenOfWord1-1]==$word2[$LenOfWord2-1])
            $d=0;
        else 
            $d=1;
        
        return min($this->minDistance(substr($word1,0,$LenOfWord1-1),$word2)+1,
                   $this->minDistance($word1,substr($word2,0,$LenOfWord2-1))+1,
                  $this->minDistance(substr($word1,0,$LenOfWord1-1),substr($word2,0,$LenOfWord2-1))+$d);
    }
}

结果在leetcode上写完提交,测试用例发现超时了,但是我也没发现题目哪里要求了时间。把strlen的结果存储起来,收效甚微。没办法,只好尝试使用动态规划。
3.2 动态规划

你可能感兴趣的:(【编程-算法】2019-10-09 编辑距离Edit-distance)