题目描述:计算相似度,其实本质就是计算编辑距离
思路:一开始先递归,然后加备忘改DP,发现有很多重复子问题,再重新设计dp算法
1 #include <iostream> 2 #include <queue> 3 #include <climits> 4 #include <algorithm> 5 #include <memory.h> 6 #include <stdio.h> 7 using namespace std; 8 9 10 int calSim_1(string s1,int b1,int e1,string s2,int b2,int e2) 11 { 12 if(b1 > e1) 13 { 14 if(b2 > e2) 15 { 16 return 0; 17 } 18 return e2 - b2 + 1; 19 } 20 if(b2 > e2) 21 { 22 if(b1 > e1) 23 { 24 return 0; 25 } 26 return e1 - b1 + 1; 27 } 28 if(s1[b1] == s2[b2]) 29 { 30 return calSim_1(s1,b1+1,e1,s2,b2+1,e2); 31 } 32 else 33 { 34 int len1 = calSim_1(s1,b1,e1,s2,b2+1,e2); 35 int len2 = calSim_1(s1,b1+1,e1,s2,b2,e2); 36 int len3 = calSim_1(s1,b1+1,e1,s2,b2+1,e2); 37 38 len1 = min(len1,len2); 39 len1 = min(len1,len3); 40 return len1+1; 41 } 42 } 43 44 //递归+备忘录版本(DP) 45 int opt[100][100]; 46 int calSim_2(string s1,int b1,int e1,string s2,int b2,int e2) 47 { 48 if(b1 > e1) 49 { 50 if(b2 > e2) 51 { 52 return 0; 53 } 54 return e2 - b2 + 1; 55 } 56 if(b2 > e2) 57 { 58 if(b1 > e1) 59 { 60 return 0; 61 } 62 return e1 - b1 + 1; 63 } 64 if(s1[b1] == s2[b2]) 65 { 66 if(opt[b1+1][b2+1] == -1) 67 { 68 opt[b1+1][b2+1] = calSim_2(s1,b1+1,e1,s2,b2+1,e2); 69 } 70 return opt[b1+1][b2+1]; 71 } 72 else 73 { 74 if(opt[b1][b2+1] == -1) 75 { 76 opt[b1][b2+1] = calSim_2(s1,b1,e1,s2,b2+1,e2); 77 } 78 int len1 = opt[b1][b2+1]; 79 if(opt[b1+1][b2] == -1) 80 { 81 opt[b1+1][b2] = calSim_2(s1,b1+1,e1,s2,b2,e2); 82 } 83 int len2 = opt[b1+1][b2]; 84 if(opt[b1+1][b2+1] == -1) 85 { 86 opt[b1+1][b2+1] = calSim_2(s1,b1+1,e1,s2,b2+1,e2); 87 } 88 int len3 = opt[b1+1][b2+1]; 89 90 len1 = min(len1,len2); 91 len1 = min(len1,len3); 92 return len1+1; 93 } 94 } 95 96 //DP+非备忘录版本 97 int dp[100][100]; 98 int calSim_3(string s1,string s2) 99 { 100 int len1 = s1.length(); 101 int len2 = s2.length(); 102 int i,j; 103 for(i = 0 ; i <= s1.length() ; ++i) 104 { 105 dp[i][0] = i; 106 } 107 for(j = 0 ; j <= s2.length() ; ++j) 108 { 109 dp[0][j] = j; 110 } 111 for(i = 1 ; i <= s1.length() ; ++i) 112 { 113 for(j = 1 ; j <= s2.length() ; ++j) 114 { 115 if(s1[i-1] == s2[j-1]) 116 { 117 dp[i][j] = dp[i-1][j-1]; 118 } 119 else 120 { 121 dp[i][j] = dp[i-1][j] + 1; 122 dp[i][j] = min(dp[i][j],dp[i][j-1]+1); 123 dp[i][j] = min(dp[i][j],dp[i-1][j-1]+1); 124 } 125 } 126 } 127 return dp[s1.length()][s2.length()]; 128 } 129 130 int main() 131 { 132 memset(opt,-1,sizeof(opt)); 133 string s1("abc"); 134 string s2("ab"); 135 cout<<calSim_3(s1,s2); 136 return 0; 137 }
我的代码里没有加边界情况检查,这一点很重要,不要向我学习,O(∩_∩)O~~