1. 程式人生 > >《演算法設計與分析》第九周作業

《演算法設計與分析》第九周作業

《演算法設計與分析》第九周作業

標籤(空格分隔): 課堂作業

文章目錄

姓名:李**
學號:16340114
題目:Edit Distance(https://leetcode.com/problems/edit-distance/description/)


題目概要

給定兩個字串,每次可以對增加、刪除、替換一個字元。問最少多少次操作後,兩個字串變得一樣。

思路

這個問題書本里有將過。思路就是將當前問題化解為若干個子問題去解決,取子問題中的最有解。子問題的情況有三:
   [設i為字串1的長度,j為字串2的長度]
  (i)string1的前(i-1)個字元與string2經過一定操作後可以變得一樣,此時只需刪掉string1的第i個字元
  (ii)string2的前(j-1)個字元與string1經過一定操作後可以變得一樣,此時只需刪掉string2的第j個字元
  (iii)string1的前(i-1)個字元與string2的前(j-1)個字元經過一定操作後可以變得一樣,此時判斷string1的第i個字元與string2的第j個字元是否相同,若不相同即進行替換操作,相同即不進行任何操作
  這樣,得到了狀態轉換方程(引自書本Algorithms(Dasgupta)

):
 在這裡插入圖片描述

具體實現

先初始化一個字串為空,另一個字串有字元的情況
  再根據狀態遷移方程程式設計即可(引自書本Algorithms(Dasgupta)):
  在這裡插入圖片描述
  需要注意,diff中的i, j是指第幾個元素,實現時需要轉換成字串下標,減去一即可。

心得

重新複習了一遍書中的例子,並親手程式設計之後,可算是有一點點領悟到動態規劃的內涵了。動態規劃的主要思想就是把當前的問題化解為一個或多個類似的子問題,就像領導佈置工作給下屬,下屬又繼續把工作分配給下屬的下屬,如此往復,當最下層的工作完成了,就逐層往上彙報,最後領導就得到一個完整的工作結果了。雖然比喻得可能不是很恰當,但大概也就是這個意思了吧。

原始碼:

class Solution 
{
public:
    int minDistance(string word1, string word2) 
    {
        int m = word1.length();
        int n = word2.length();

        int** E = new int* [m+1];
        for (int i = 0; i <= m; ++i)
            E[i] = new int [n+1];

        for (int i = 0; i <= m; ++i)
            E[i][0] = i;

        for (int j = 0; j <= n; ++j)
            E[0][j] = j;
        
        for (int i = 1; i <= m; ++i)
            for (int j = 1; j <= n; ++j)
                E[i][j] = min(E[i-1][j] + 1, E[i][j-1] + 1, E[i-1][j-1] + (word1[i-1] != word2[j-1]));

        return E[m][n];
    }

    int min(int a, int b, int c)
    {
        int min = a;
        if (b < min)
            min = b;
        if (c < min)
            min = c;
        return min;
    }
};