动态规划---字符串编辑问题

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];
    }
发布了184 篇原创文章 · 获赞 60 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/StubbornAccepted/article/details/103069459