動態規劃---字符串編輯問題

1.編輯距離

   /*
    * 最小編輯代價
    * */
    public int minCost(String str1,String str2,int ic,int dc,int rc){
        if(str1==null||str2==null) return 0;
        char s1[]=str1.toCharArray();
        char s2[]=str2.toCharArray();
        int n1=s1.length;
        int n2=s2.length;
        int dp[][]=new int[n1+1][n2+1];//dp[i][j]表示s1中前i-1個字符s1[0...i-1]轉化爲s2中前j-1個字符s2[0...j-1]需要的最小編輯代價.
        // dp[0][0]代表''->'',所以dp[0][0]=0
        for(int i=1;i<=n1;i++){//用s1[0...i]轉化爲''的最小編輯代價
            dp[i][0]=i*dc;
        }
        for(int j=1;j<=n2;j++){//用‘’轉化爲s2[0...j]的最小編輯代價
            dp[0][j]=j*ic;
        }
        for(int i=1;i<=n1;i++){
            for(int j=1;j<=n2;j++){
                if(s1[i-1]==s2[j-1]){//s1[i-1]==s[j-1]時,s1[0...i-1]轉化爲s2[0...j-1]的代價就是 s1[0...i-2]轉化爲s2[0...j-2],即dp[i-1][j-1]
                    dp[i][j]=dp[i-1][j-1];
                }else{//s1[i]!=s[j]時,s1[0...i-1]轉化爲s2[0...j-1]的代價就是 s1[0...i-2]轉化爲s2[0...j-2]的代價加上一個替換操作(s1[i-1]->s2[i-1])的代價,即dp[i-1][j-1]+rc.
                    dp[i][j]=dp[i-1][j-1]+rc;
                }
                dp[i][j]=Math.min(dp[i][j],dp[i-1][j]+rc);//比較此時的代價取小:用s1[0...i-2]編輯成s2[0...j-1]的代價,加上一個刪除s1[i-1]的操作
                dp[i][j]=Math.min(dp[i][j],dp[i][j-1]+ic);//比較此時的代價取小:用s1[0...i-1]編輯成s2[0...j-2]的代價,加上一個添入s2[i-1]的操作
            }
        }
        return dp[n1][n2];
    }

    /*
    * 題目:編輯距離
    * 題目描述:
    * 給定兩個單詞 word1 和 word2,計算出將 word1 轉換成 word2 所使用的最少操作數 。
    * 你可以對一個單詞進行如下三種操作:
    * 插入一個字符;刪除一個字符;替換一個字符
    * */
    public int minDistance2(String word1, String word2) {
        return  minCost(word1,word2,1,1,1);
    }


2.複製粘貼字符

    /*
   * 題目描述:複製粘貼字符
   * 題目描述:最開始只有一個字符 A,問最少需要多少次操作能夠得到 n 個字符 A,每次操作可以複製當前所有的字符,或者粘貼。
   *
   * */
    public int minSteps(int n) {
        int dp[]=new int[n+1];//dp[i]表示得到i個字符需要的最少步數
        dp[1]=0;
        /*
        * 得到i個字符的方式只能是如下兩種方案之一:(比較所有方案找到操作次數最少的那個)
        * 1.複製1個字符後,粘貼i-1次
        * 2.找到i的因數j,複製1次(i/j)個字符,粘貼j-1次。(第二種方式計算dp[i]的前提是已知dp[i/j],所以可以用動態規劃的方式,依次計算dp[i]並保存)
        * */
        for(int i=2;i<=n;i++){
            dp[i]=i;
            for(int j=2;j<=Math.sqrt(n);j++){
                if(i%j==0) dp[i]=Math.min(dp[i],dp[i/j]+j);
            }
        }
        return dp[n];
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章