91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++怎么編輯距離

發布時間:2022-03-28 13:53:35 來源:億速云 閱讀:144 作者:iii 欄目:大數據

這篇文章主要介紹“C++怎么編輯距離”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“C++怎么編輯距離”文章能幫助大家解決問題。

編輯距離

Example 1:

Input: word1 = "horse", word2 = "ros"
Output: 3
Explanation:
horse -> rorse (replace "h" with "r")
rorse -> rose (remove "r")
rose -> ros (remove "e")

Example 2:

Input: word1 = "intention", word2 = "execution"
Output: 5
Explanation:
intention -> inention (remove "t")
inention -> enention (replace "i" with "e")
enention -> exention (replace "n" with "x")
exention -> exection (replace "n" with "c")
exection -> execution (insert "u")

這道題讓求從一個字符串轉變到另一個字符串需要的變換步驟,共有三種變換方式,插入一個字符,刪除一個字符,和替換一個字符。題目乍眼一看并不難,但是實際上卻暗藏玄機,對于兩個字符串的比較,一般都會考慮一下用 HashMap 統計字符出現的頻率,但是在這道題卻不可以這么做,因為字符串的順序很重要。還有一種比較常見的錯誤,就是想當然的認為對于長度不同的兩個字符串,長度的差值都是要用插入操作,然后再對應每位字符,不同的地方用修改操作,但是其實這樣可能會多用操作,因為刪除操作有時同時可以達到修改的效果。比如題目中的例子1,當把 horse 變為 rorse 之后,之后只要刪除第二個r,跟最后一個e,就可以變為 ros。實際上只要三步就完成了,因為刪除了某個字母后,原來左右不相連的字母現在就連一起了,有可能剛好組成了需要的字符串。所以在比較的時候,要嘗試三種操作,因為誰也不知道當前的操作會對后面產生什么樣的影響。對于當前比較的兩個字符 word1[i] 和 word2[j],若二者相同,一切好說,直接跳到下一個位置。若不相同,有三種處理方法,首先是直接插入一個 word2[j],那么 word2[j] 位置的字符就跳過了,接著比較 word1[i] 和 word2[j+1] 即可。第二個種方法是刪除,即將 word1[i] 字符直接刪掉,接著比較 word1[i+1] 和 word2[j] 即可。第三種則是將 word1[i] 修改為 word2[j],接著比較 word1[i+1] 和 word[j+1] 即可。分析到這里,就可以直接寫出遞歸的代碼,但是很可惜會 Time Limited Exceed,所以必須要優化時間復雜度,需要去掉大量的重復計算,這里使用記憶數組 memo 來保存計算過的狀態,從而可以通過 OJ,注意這里的 insertCnt,deleteCnt,replaceCnt 僅僅是表示當前對應的位置分別采用了插入,刪除,和替換操作,整體返回的最小距離,后面位置的還是會調用遞歸返回最小的,參見代碼如下:

解法一:

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.size(), n = word2.size();
        vector<vector<int>> memo(m, vector<int>(n));
        return helper(word1, 0, word2, 0, memo);
    }
    int helper(string& word1, int i, string& word2, int j, vector<vector<int>>& memo) {
        if (i == word1.size()) return (int)word2.size() - j;
        if (j == word2.size()) return (int)word1.size() - i;
        if (memo[i][j] > 0) return memo[i][j];
        int res = 0;
        if (word1[i] == word2[j]) {
            return helper(word1, i + 1, word2, j + 1, memo);
        } else {
            int insertCnt = helper(word1, i, word2, j + 1, memo);
            int deleteCnt = helper(word1, i + 1, word2, j, memo);
            int replaceCnt = helper(word1, i + 1, word2, j + 1, memo);
            res = min(insertCnt, min(deleteCnt, replaceCnt)) + 1;
        }
        return memo[i][j] = res;
    }
};

根據以往的經驗,對于字符串相關的題目且求極值的問題,十有八九都是用動態規劃 Dynamic Programming 來解,這道題也不例外。其實解法一的遞歸加記憶數組的方法也可以看作是 DP 的遞歸寫法。這里需要維護一個二維的數組 dp,其大小為 mxn,m和n分別為 word1 和 word2 的長度。dp[i][j] 表示從 word1 的前i個字符轉換到 word2 的前j個字符所需要的步驟。先給這個二維數組 dp 的第一行第一列賦值,這個很簡單,因為第一行和第一列對應的總有一個字符串是空串,于是轉換步驟完全是另一個字符串的長度。跟以往的 DP 題目類似,難點還是在于找出狀態轉移方程,可以舉個例子來看,比如 word1 是 "bbc",word2 是 "abcd",可以得到 dp 數組如下:

  ? a b c d
? 0 1 2 3 4
b 1 1 1 2 3
b 2 2 1 2 3
c 3 3 2 1 2

通過觀察可以發現,當 word1[i] == word2[j] 時,dp[i][j] = dp[i - 1][j - 1],其他情況時,dp[i][j] 是其左,左上,上的三個值中的最小值加1,其實這里的左,上,和左上,分別對應的增加,刪除,修改操作,具體可以參見解法一種的講解部分,那么可以得到狀態轉移方程為:

dp[i][j] =      /    dp[i - 1][j - 1]                                                                   if word1[i - 1] == word2[j - 1]

                      min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1            else

解法二:

class Solution {
public:
    int minDistance(string word1, string word2) {
        int m = word1.size(), n = word2.size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1));
        for (int i = 0; i <= m; ++i) dp[i][0] = i;
        for (int i = 0; i <= n; ++i) dp[0][i] = i;
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (word1[i - 1] == word2[j - 1]) {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1;
                }
            }
        }
        return dp[m][n];
    }
};

關于“C++怎么編輯距離”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

阳高县| 岳普湖县| 奎屯市| 义马市| 霍邱县| 金山区| 和硕县| 微山县| 涞水县| 临潭县| 响水县| 福海县| 饶河县| 会同县| 文水县| 井冈山市| 彝良县| 长白| 香港| 县级市| 宁波市| 长沙县| 邵阳市| 肇庆市| 柳江县| 徐闻县| 灵璧县| 南康市| 仙游县| 翼城县| 太白县| 中山市| 金湖县| 镇康县| 长丰县| 合水县| 拜泉县| 仁寿县| 沙田区| 新野县| 南川市|