编辑距离及其算法

  现在定义字符串上的操作有一下几种:
  1. 添加一个字符;
  2. 删除一个字符;
  3. 修改一个字符。
即允许对字符串的操作有以上3种,那么使得2个字符串相等执行的最少编辑步骤为多少?也就是说,可以对2个串都进行以上3种操作,最少的操作次数。其也就是所谓的编辑距离。

现在我们可以使用动态规划:
设源字符串 s的长度 i=s.length(),另外一个字符串 rj=r.length(),那么有:
1.如果i=j=0,显然有编辑次数d=0;
2.如果有i=0(i=1)或者j=1(j=0),显然有编辑次数d=1;(即删除r中的字符或则添加s中字符即可)
          显然使得2个串相等的操作不会超过2个字符串所有字符之和。(删除所有的字符)
3、当i>1且j>1时,我们可以使用动态规划,将问题划分为等价的子问题:
        编辑距离及其算法

其中cost=0或者1,即当第i个字符和第j个字符相同时候,cost=0,否则为1.
另外上述3个sub 式子分别表示删除s串第i个字符,删除r(增加s)串第j个字符(串第i个字符),替换s串第i个字符为r串第j个字符。

上述算法即为著名的 编辑距离算法 ,又称 Levenshtein距离算法。
c++代码如下:

#include 
#include <<span style="color: rgb(0, 0, 255); font-family: 'Courier New' !important;">string>

using namespace std;

int min(int a, int b)
{
    return a < b ? a : b;
}

int edit(string str1, string str2)
{
    int max1 = str1.size();
    int max2 = str2.size();

    int **ptr = new int*[max1 + 1];
    for(int i = 0; i < max1 + 1 ;i++)
    {
        ptr[i] = new int[max2 + 1];
    }

    for(int i = 0 ;i < max1 + 1 ;i++)
    {
        ptr[i][0] = i;
    }

    for(int i = 0 ;i < max2 + 1;i++)
    {
        ptr[0][i] = i;
    }

    for(int i = 1 ;i < max1 + 1 ;i++)
    {
        for(int j = 1 ;j< max2 + 1; j++)
        {
            int d;
            int temp = min(ptr[i-1][j] + 1, ptr[i][j-1] + 1);
            if(str1[i-1] == str2[j-1])
            {
                d = 0 ;
            }
            else
            {
                d = 1 ;
            }
            ptr[i][j] = min(temp, ptr[i-1][j-1] + d);
        }
    }

    cout << "**************************" << endl;
    for(int i = 0 ;i < max1 + 1 ;i++)
    {
        for(int j = 0; j< max2 + 1; j++)
        {
            cout << ptr[i][j] << " " ;
        }
        cout << endl;
    }
    cout << "**************************" << endl;
    int dis = ptr[max1][max2];

    for(int i = 0; i < max1 + 1; i++)
    {
        delete[] ptr[i];
        ptr[i] = NULL;
    }

    delete[] ptr;
    ptr = NULL;

    return dis;
}

int main(void)
{
    string str1 = "sailn";
    string str2 = "failing";

    int r = edit(str1, str2);
    cout << "the dis is : " << r << endl;

    return 0;
}



文中部分内容引用自参考文献,感谢原作者的贡献。

1.编辑距离及编辑距离算法

2、从K近邻算法、距离度量谈到KD树、SIFT+BBF算法


你可能感兴趣的:(编辑距离及其算法)