Edit Distance

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

思想:利用动态规划的思想求解,distance[i][j]表示word1前i个字符和word2前j个字符所需要的最小编辑次数;而distance[i][j]肯定由distance[i-1][j] 和distance[i][j-1]以及distance[i-1][j-1]转变来的。从而可以得到

distance[i][j] = min { distance[i-1][j] + 1,distance[i][j-1] + 1,distance[i-1][j-1] + (word1[i-2]==word2[j-2]?0:1) } 

这里要注意+ 与 == (?:) 之间的优先级,要形成良好的编码习惯,根据思考流程加入括号。

  1. public int minDistance(String word1, String word2) {
  2. int wlen1 = word1.length();
  3. int wlen2 = word2.length();
  4. int[][] distance = new int[wlen1+1][wlen2+1]; //多申请一个长度
  5. distance[0][0] = 0;
  6. for(int i=1;i<=wlen1;i++) {
  7. distance[i][0] = i;
  8. }
  9. for(int i=1;i<=wlen2;i++) {
  10. distance[0][i] = i;
  11. }
  12. for(int i=1;i<=wlen1;i++) {
  13. for(int j=1;j<=wlen2;j++) {
  14. int cost = (word1.charAt(i-1) == word2.charAt(j-1) ? 0:1); //注意括号,保证正确优先级
  15. distance[i][j] = Math.min(distance[i-1][j]+1,Math.min(distance[i][j-1]+1,distance[i-1][j-1]+cost));
  16. }
  17. }
  18. return distance[wlen1][wlen2];
  19. }

 

改进:可以backward的思想得到每次的操作,由于可能存在多条路径,可以今选择一条。

代码如下:

  1. int dp[100][100];
  2. typedef struct {
  3. int left;
  4. int down;
  5. int slope;
  6. } Direct;
  7. Direct direct[100];
  8. int minimalEditDistance(string s1,string s2) {
  9. int s1len = s1.size();
  10. int s2len = s2.size();
  11. for(int i=1;i<=s2len;i++) {
  12. dp[0][i] = i;
  13. }
  14. for(int i=1;i<=s1len;i++) {
  15. dp[i][0] = i;
  16. }
  17. dp[0][0] = 0;
  18. for(int i=1;i<=s1len;i++) {
  19. for(int j=1;j<=s2len;j++) {
  20. dp[i][j] = min(dp[i-1][j]+1,dp[i][j-1]+1);
  21. dp[i][j] = min(dp[i][j],dp[i-1][j-1]+(s1[i-1]==s2[j-1]?0:1));
  22. cout<<i<<'\t'<<j<<'\t'<<dp[i][j]<<endl;
  23. int cnt=0;
  24. if(dp[i][j]==dp[i-1][j]+1) {
  25. direct[i].left = 1;
  26. } else if(dp[i][j]==dp[i][j-1]) {
  27. direct[i].down = 1;
  28. } else {
  29. direct[i].slope = 1;
  30. }
  31. }
  32. }
  33. return dp[s1len][s2len];
  34. }
  35. int main() {
  36. //input the string s1 and s2
  37. string s1 = "abc";
  38. string s2 = "a";
  39. memset(direct,0,sizeof(direct));
  40. cout<< minimalEditDistance(s1,s2) <<endl;
  41. for(int i=s1.length();i>=1;i--) {
  42. if(direct[i].left == 1) {
  43. cout<<"deletion"<<endl;
  44. } else if(direct[i].down == 1) {
  45. cout<<"insert"<<endl;
  46. } else {
  47. cout<<"substitution"<<endl;
  48. }
  49. }
  50. }
posted @ 2014-07-10 00:03  purejade  阅读(179)  评论(0)    收藏  举报