【问题标题】:Edit distance - With memoization编辑距离 - 带记忆
【发布时间】:2013-11-04 03:43:06
【问题描述】:

我正在尝试解决编辑距离问题,但会缓存结果,以免重复调用。在我尝试将子问题存储在地图中之前它可以工作,但现在它停止工作了。对于我打的电话,比较“你不应该”和“你不应该”,它返回 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;
}

【问题讨论】:

  • 匹配函数的返回值在哪里?不应该是 return c1 == c2 吗? 0 : 1;

标签: c++ algorithm dynamic-programming


【解决方案1】:

否则,我认为您在提取前缀时有问题,您应该使用:s1.substr(0,s1.size()-1) 消除字符串中的最后一个字符。

【讨论】:

    【解决方案2】:

    问题出在这里:

    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;
    }
    

    然后your code prints 6 for those strings

    【讨论】: