zoukankan      html  css  js  c++  java
  • 【Edit Distance】cpp

    题目:

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2. (each operation is counted as 1 step.)

    You have the following 3 operations permitted on a word:

    a) Insert a character
    b) Delete a character
    c) Replace a character

    代码:

    class Solution {
    public:
        int minDistance(string word1, string word2) {
                const int n1 = word1.size();
                const int n2 = word2.size();
                // initialization
                vector<vector<int> > dp(n1+1,vector<int>(n2+1,0));
                dp[0][0] = 0;
                for ( int j=1; j<=n2; ++j ) dp[0][j] = dp[0][j-1]+1;
                for ( int i=1; i<=n1; ++i ) dp[i][0] = dp[i-1][0]+1;
                // dp process
                for ( int i=1; i<=n1; ++i )
                {
                    for ( int j=1; j<=n2; ++j )
                    {
                        if ( word1[i-1]==word2[j-1] )
                        {
                            dp[i][j] = dp[i-1][j-1];
                        }
                        else
                        {
                            int rep = dp[i-1][j-1] + 1; // replace
                            int del = dp[i-1][j] + 1;   // delete
                            int ins = dp[i][j-1] + 1;   // insert
                            dp[i][j] = std::min(rep,std::min(del, ins));
                        }
                    }
                }
                return dp[n1][n2];
        }
    };

    tips:

    不知道这是一个经典的DP案例,确实首次感到DP算法挺精妙的,很多无法想清楚理清楚的事情,交给DP就好了。

    参考了两个网上blog的解释:

    http://fisherlei.blogspot.sg/2012/12/leetcode-edit-distance.html

    http://bangbingsyb.blogspot.sg/2014/11/leetcode-edit-distance.html

    dp[i][j]表示s1[0~i-1]与s2[0~j-1]的编辑距离:

    根据题意,计算dp[i][j]分如下几种情况:

    1. 如果s1[i-1]==s2[j-1] 则不用三种操作,直接dp[i][j] = dp[i-1][j-1]

    2. 如果s1[i-1]!=s2[j-1] 则需要在上几步的基础上进行匹配操作:

      a) 如果直接选择替换则 dp[i][j] = dp[i-1][j-1] + 1

        翻译过来就是:s1[0~i-2]与s2[0~j-2]已经对上了,把s1[i-1]的值换成s2[j-1]的值,替换之;

      b) 如果选择删除操作则 dp[i][j] = dp[i-1][j] + 1

        翻译过来就是:s1[0~i-2]与s2[0~j-1]已经对上了,这个s1[i-1]就是多余的了,删除之;

      c) 如果选择插入操作则 dp[i][j] = dp[i][j-1] + 1

        翻译过来就是:s1[0~i-1]与s2[0~j-2]已经对上了,因此少s1当前坐标后面再不上一个s2[j-1]这个值就OK了,插入之;

    按照上述的过程,就可以写出来代码了。

    为什么每次都加1呢?因为字符要一个一个匹配。

    “插入”、“替换”、“删除”什么时候出现是有讲究的。最优的情况就是这些操作单独就可以完成转换,所以要选择出现的情况。

    =============================================

    第二次过这道题,一开始忘记了word1[i-1]==word2[j-1]的情况,改了之后AC了。

    class Solution {
    public:
        int minDistance(string word1, string word2) {
                if ( word1==word2 ) return 0;
                int dp[word1.size()+1][word2.size()+2];
                fill_n(&dp[0][0], (word1.size()+1)*(word2.size()+1), 0);
                for ( int i=1; i<=word1.size(); ++i ) dp[i][0] = dp[i-1][0]+1;
                for ( int i=1; i<=word2.size(); ++i ) dp[0][i] = dp[0][i-1]+1;
                // dp process
                for ( int i=1; i<=word1.size(); ++i )
                {
                    for ( int j=1; j<=word2.size(); ++j )
                    {
                        if ( word1[i-1]==word2[j-1] ) 
                        {
                            dp[i][j] = dp[i-1][j-1];
                            continue;
                        }
                        // insert
                        int ins = dp[i][j-1]+1;
                        // delete
                        int del = dp[i-1][j]+1;
                        // replace
                        int rep = dp[i-1][j-1]+1;
                        dp[i][j] = min(ins,min(del,rep));
                    }
                }
                return dp[word1.size()][word2.size()];
        }
    };
  • 相关阅读:
    公钥,私钥和数字签名这样最好理解
    SolrCloud的官方配置方式
    由于Windows和Linux行尾标识引起脚本无法运行的解决
    python模块名和文件名冲突解决
    Linux下编译安装python3
    Storm集群的安装配置
    Linux下编译安装Apache 2.4
    SELinux的关闭与开启
    Spring MVC配置静态资源的正常访问
    SolrCloud环境配置
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4551027.html
Copyright © 2011-2022 走看看