我正在尝试编辑距离问题,但是缓存结果以便我不重复调用。它在我尝试将子问题存储在地图中之前工作,但现在它停止工作。对于我的电话,比较“你不应该”和“你不应该”,它会返回1.显然是不正确的,但为什么呢?
using namespace std;
int counter = 0;
int match(char c1, char c2){
c1 == c2 ? 0 : 1;
}
int edit_distance(string s1, string s2,map<pair<string,string>, int>& memo){
if(memo[make_pair(s1,s2)])
return memo[make_pair(s1,s2)];
int i = s1.size();
int j = s2.size();
if(s1.empty())
return memo[make_pair(s1,s2)] = 1 + j;
if(s2.empty())
return memo[make_pair(s1,s2)] = 1 + i;
int opt[3];
opt[0] = edit_distance(s1.substr(1), s2.substr(1),memo) + match(s1[i-1],s2[j-1]);
opt[1] = edit_distance(s1.substr(1), s2,memo) + 1;
opt[2] = edit_distance(s1, s2.substr(1),memo) + 1;
int min = opt[0];
for(int i = 1; i < 3; i++){
if(opt[i] < min)
min = opt[i];
}
memo[ make_pair(s1,s2) ] = min;
return min;
}
int edit_distance_driver(string s1, string s2){
map<pair<string,string>,int> memo;
return edit_distance(s1, s2, memo);
}
int main(){
cout << edit_distance_driver("thou shalt not","you should not") << endl;
}
答案 0 :(得分:4)
问题在于:
opt[0] = edit_distance(s1.substr(1), s2.substr(1),memo) + match(s1[i-1],s2[j-1]);
您在没有第一个字符的情况下递归,但检查最后字符。
你应该检查第一个字符,所以它应该是:
opt[0] = edit_distance(s1.substr(1), s2.substr(1),memo) + match(s1[0],s2[0]);
显然match
应该返回一些内容:
int match(char c1, char c2){
return c1 == c2 ? 0 : 1;
}
答案 1 :(得分:0)
否则,我认为您在提取前缀时遇到问题,您应该使用:s1.substr(0,s1.size()-1)
消除字符串中的最后一个字符。