编程之美 3.3 计算字符串的相似度

主要思想为递归求解,每一次都需要计算三种情况下的最小值。需要注意的是几个条件:

1、一旦begin>end,则结束当前递归,返回值为0;

2、如果当前pAbegin == pBbegin,则两个指针都直接跳到下一个字符;

这里给出用map保存递归过程每一次的指针状态,以避免重复的递归计算(除结束状态,因为结束状态的计算无需递归,开销更小);

定义MapCmp访函数做为排序准则时,需要注意满足三个条件,即strict weak ordering(反对称,可传递,非自反(这个容易遗忘));

 

#include<iostream>
#include<string>
#include<map>
using namespace std;
class TempVar{
public:
TempVar(int a, int b){
pAbegin = a;
pBbegin = b;
}
int pAbegin;
int pBbegin;
};

class MapCmp{
public:
bool operator()(const TempVar &t1, const TempVar &t2){
if (t1.pAbegin < t2.pAbegin)
return true;
else if(t2.pAbegin < t1.pAbegin)
return false;
if (t1.pBbegin < t2.pBbegin)
return true;
else if(t2.pBbegin < t1.pBbegin)
return false;
return false;
}
};
typedef std::map<TempVar, int, MapCmp> MapTemps;
MapTemps mapTemps;
int count = 0;
int min(int a, int b, int c){
return a < b ? (a < c ? a : c) : (b < c ? b : c);
}

int calculateStrDistance(const string &s1, const string &s2, int pAbegin, int
pAend, int pBbegin, int pBend){
if(pAbegin > pAend)
return pBend - pBbegin + 1;
if(pBbegin > pBend)
return pAend - pAbegin + 1;

TempVar temp =TempVar(pAbegin, pBbegin);
MapTemps::iterator iter = mapTemps.find(temp);
if (iter != mapTemps.end()){
count++;
return iter -> second;
}
if(s1[pAbegin] == s2[pBbegin]){
int x = calculateStrDistance(s1, s2, pAbegin + 1, pAend, pBbegin + 1,
pBend);
mapTemps.insert(std::make_pair(temp, x));
return x;
}
int t1 = calculateStrDistance(s1, s2, pAbegin + 1, pAend, pBbegin,
pBend);
int t2 = calculateStrDistance(s1, s2, pAbegin, pAend, pBbegin + 1,
pBend);
int t3 = calculateStrDistance(s1, s2, pAbegin + 1, pAend, pBbegin + 1,
pBend);
int x = min(t1, t2, t3) + 1;
mapTemps.insert(std::make_pair(temp, x));
return x;

}
int main(){
std::string str1, str2;
cin >> str1 >> str2;
cout << calculateStrDistance(str1, str2, 0, str1.length() - 1, 0,
str2.length() - 1) << endl;
cout << mapTemps.size() <<endl;
cout << count << endl;
return 1;
}

 

posted on 2012-12-21 00:33  小龙人2012  阅读(146)  评论(0编辑  收藏  举报

导航