双字符串DP小结

作者: stepsma | 来源:发表于2016-12-02 23:48 被阅读0次

    本文总结一下一些双字符串的DP问题。具体解法是要建立以两个字符串为边的矩阵。

    vector<vector<int>> dp(lenA+1, vector<int>(lenB+1, 0)); \\ 要加1
    

    dp[i][j] 为以A[i]结尾,和B[j]结尾的满足条件解。

        0 a b c d
    0   
    a
    c
    m
    n
    

    Longest Common Sub-sequence:

    这道题的点是sub-sequence可以不连续。
    dp[i][j] = 以A[i], B[j]为结尾,的最长sub-sequence长度。通项公式为

    if(A[i] == B[j]) dp[i][j] = dp[i-1][j-1]+1;
    else dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
    
    int longestRepeatingSubsequence(string& str) {
            // Write your code here
            int len = str.length();
            vector<vector<int>> dp(len+1, vector<int>(len+1, 0));
            for(int i=1; i<=len; i++){
                for(int j=1; j<=len; j++){
                    if(str[i-1] == str[j-1] && i != j){
                        dp[i][j] = 1 + dp[i-1][j-1];
                    }else{
                        dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
                    }
                }
            }
            return dp[len][len];
        }
    

    Longest Common Substring:

    这道题要点是sub-string必须连续,
    dp[i][j] = 以A[i], B[j]为结尾,的最长sub-string长度 (必须包含A[i], B[j])。通项公式为:

    if(A[i] == B[j]) dp[i][j] = dp[i-1][j-1] + 1;
    else dp[i][j] = 0;
    

    然后新添一个max_len变量,打擂台, 找最长。

    int longestCommonSubstring(string &A, string &B) {
            // write your code here
            if(A.empty() || B.empty()) return 0;
            int lenA = A.size(), lenB = B.size();
            vector<vector<int>> dp(lenA+1, vector<int>(lenB+1, 0));
            int max_len = 0;
            for(int i=1; i<=lenA; i++){
                for(int j=1; j<=lenB; j++){
                    if(A[i-1] == B[j-1]){
                        dp[i][j] = dp[i-1][j-1] + 1;
                    }else{
                        dp[i][j] = 0;
                    }
                    if(dp[i][j] > max_len) max_len = dp[i][j];
                }
            }
            return max_len;
        }
    

    Edit Distance

    这道题的要点是下面的表达式。表示新加一个,删除一个,和edit一个。
    dp[i][j]为以A[i], B[j]为结尾的最短edit distance。通项公式为:

    dp[i][j] = min(dp[i-1][j-1], min(dp[i-1][j], dp[i][j-1])) + 1;
    
     int minDistance(string word1, string word2) {
            // write your code here
            if(word1.empty()) return word2.length();
            else if(word2.empty()) return word1.length();
            int lenA = word1.length(), lenB = word2.length();
            vector<vector<int>> dp(lenA+1, vector<int>(lenB+1, 0));
            for(int i=0; i<=lenA; i++){
                dp[i][0] = i;
            }
            for(int i=0; i<=lenB; i++){
                dp[0][i] = i;
            }
            for(int i=1; i<=lenA; i++){
                for(int j=1; j<=lenB; 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[lenA][lenB];
        }
    

    相关文章

      网友评论

        本文标题:双字符串DP小结

        本文链接:https://www.haomeiwen.com/subject/ncnqmttx.html