leecode 解题总结:72. Edit Distance

来源:互联网 发布:union软件 编辑:程序博客网 时间:2024/05/22 00:30
#include <iostream>#include <stdio.h>#include <vector>#include <string>using namespace std;/*问题: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 characterb) Delete a characterc) Replace a character分析:这是字符串变换,求一个字符串通过每次插入,删除,替换1个字符的方式变换成另一个字符串。求操作次数。这个应该是编程之美的一道题目。举例: abc,bcce; abc, abcc ; abcdef , bcdefa 由于长度不等因此必定要对较短的字符串插入字符,关键插入字符的位置和字符本身的值不容易确定。而如果删除较长的字符的话,必定是从较长字符串中选择一个删除,则删除的字符值和位置是可以确定。因此相比较下:删除应该比插入容易。发现:应该优先替换,如果不能替换就删除,再不行就插入这个题目应该是类似回溯,递归的解法。如果两个字符串相等,直接次数为.输入:abcdefg abcdef abcd ab machao mayan 输出:123关键:1编程之美的解法:设字符串A,字符串B,长度分别为lenA,lenB1】可以考虑线比较字符串A和B的第一个字符,如果相等,继续比较A[2...lenA]和B[2...lenB],如果不等,进行2】操作2】2.1】删除A字符串第一个字符,比较A[2...lenA]和B[1...lenB]2.2】删除B字符串第一个字符,比较A[1...lenA]和B[2...lenB]2.3】插入A字符串的第一个字符给B,比较A[2...lenA]和B[1...lenB]2.4】插入A字符串的第一个字符给A,比较A[1...lenA]和B[2...lenB]2.5】替换A字符串第一个字符为B的第一个字符,比较A[2...lenB]和B[2...lenB]2.6】替换B字符串第一个字符为A的第一个字符,比较A[2...lenB]和B[2...lenB]则都是在一步操作后比较:1】A[1...lenA]和B[2...lenB],2】A[2...lenA]和B[1...lenB],3】A[2...lenB]和B[2...lenB]三种情况具体实现递归,需要一个dis[lenA][lenB]的数组,设dis[i][j]表示字符串A[i...lenA]和B[j...lenB]的最短距离之所以没想出来,是没有考虑比较字符的位置情况问题,以及如果首个字符不相等需要选择: min(dis[beg1+1][beg2], dis[beg1][beg2+1],dis[beg1+1][beg2+1]) + 1*/class Solution {public:int minNum(int a, int b, int c){int result = min(min(a, b) , min(a , c) );return result;}//这里默认从长字符串变换到短字符串,也就是只修改长字符串int dfs(string& word1, string& word2 ,int beg1  , int end1 , int beg2 , int end2 , vector< vector<int> >& distance){        //如果一个字符串遍历完了,那么令返回的距离值就是:另一个字符串结束位置 - 起始位置 + 1,等于最后一个字符就遍历结束了if(beg1 > end1){//另一个字符串也结束了,返回0if(beg2 > end2){return distance[beg1][beg2] = 0;}//返回另一个字符串剩余字符即为需要走的距离else{return distance[beg1][beg2] = (end2 - beg2 + 1);}}if(beg2 > end2){if(beg1 > end1){return distance[beg1][beg2] = 0;}else{return distance[beg1][beg2] = (end1 - beg1 + 1);}}//如果当前字符相等,那么直接计算dis[beg1+1][beg2+1]if(word1.at(beg1) == word2.at(beg2)){//记忆化搜索,如果已经计算出if( distance.at(beg1+1).at(beg2+1) != -1 ){return distance.at(beg1+1).at(beg2+1);}//需要递归计算else{return  distance.at(beg1+1).at(beg2+1) = dfs(word1 , word2 , beg1 + 1 , end1 , beg2 + 1 , end2 , distance);}}//如果首个字符不相等需要选择: min(dis[beg1+1][beg2], dis[beg1][beg2+1],dis[beg1+1][beg2+1]) + 1else{int dis1;int dis2;int dis3;if( distance.at(beg1+1).at(beg2) != -1 ){dis1 = distance.at(beg1+1).at(beg2) ;}else{dis1 = dfs(word1 , word2 , beg1+1 , end1 , beg2 , end2 , distance);}if( distance.at(beg1).at(beg2+1) != -1 ){dis2 = distance.at(beg1).at(beg2+1) ;}else{dis2 = dfs(word1 , word2 , beg1 , end1 , beg2 + 1 , end2 , distance);}if( distance.at(beg1+1).at(beg2+1) != -1 ){dis3 = distance.at(beg1+1).at(beg2+1) ;}else{dis3 = dfs(word1 , word2 , beg1+1 , end1 , beg2+1 , end2 , distance);}return distance.at(beg1).at(beg2) = ( minNum(dis1 , dis2 , dis3) + 1 );}}    int minDistance(string word1, string word2) {if(word1.empty() && word2.empty()){return 0;}else if(word1.empty()){return word2.length();}else if(word2.empty()){return word1.length();}int beg1 = 0;int beg2 = 0;int end1 = word1.length();int end2 = word2.length();//这里初始化的距离矩阵长度需要多加1,因为后续会继续累加一次,如果不加,就溢出了vector< vector<int> > distance( end1 + 1 , vector<int> (end2 + 1 , -1) );int result = dfs(word1, word2 ,beg1  , end1 - 1 , beg2 , end2 -1 , distance);return result;    }};void process(){ string word1; string word2; Solution solution; while(cin >> word1 >> word2) { int result = solution.minDistance(word1 , word2); cout << result << endl; }}int main(int argc , char* argv[]){process();getchar();return 0;}

0 0