编辑距离算法



编辑距离:

           一个单词变换成另一个单词所需的步数,基本步骤:增加一个字符,减少一个字符,修改一个字符。 应用:搜索的时候使用ipone-->iphone,编辑距离为1,在类似文本纠错的项目中,找出编辑距离最小的值(可以用priority _queue),实现模糊匹配!

 1.英文

int Edit_Distenceen(const string &s1, 
                    const string &s2)
    {
        int cnt[s1.size() + 1 ][s2.size() + 1] ;
        size_t i, j;
        for(i = 0; i <= s1.size(); i++)
            for(j = 0; j <= s2.size(); j++)
            {
                if(i == 0)
                {
                    cnt[i][j] = j;
                    continue;
                }
                if(j == 0)
                {
                    cnt[i][j] = i;
                    continue;
                }
                if(s1[i-1] == s2[j-1])
                {
                    cnt[i][j] = cnt[i-1][j-1];
                }
                else
                {
                    int t1 = cnt[i-1][j-1] + 1;
                    int t2 = cnt[i][j-1] + 1;
                    int t3 = cnt[i-1][j] + 1;
                    cnt[i][j] = (t1 <= (t2 <= t3 ? t2 : t3 ) ? 
                            t1 : (t2 <= t3 ? t2 : t3));
                }
            }
        return cnt[s1.size()][s2.size()];

    }


2.中文utf-8格式

utf-8可以根据字的第一个字节移位推出长度的

0xxxxxxx

110xxxxx 10xxxxxx

1110xxxx 10xxxxxx 10xxxxxx

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

utf-8格式的汉字占2~4个字节,一般占3个字节

转化成一个uint32_t类型,使用数组来计算编辑距离

 //把每个汉字转化成一个uint32_t无符号32位整型    
    static void str_to_vec(const string &, vector<uint32_t> &);
    static int getlen(unsigned char c)
    {
        int cnt = 0;
        while(c & (1 << (7-cnt)))
            ++cnt;
        return cnt;
    }//返回前面有多少个连续的1,汉字的utf-8含3个字节1110xxxx  10xxxxxx 10xxxxxx

    int Edit_Distencecn(const string &str1, 
            const string &str2)
    {
        vector<uint32_t> s1;
        vector<uint32_t> s2;
            str_to_vec(str1, s1);
        str_to_vec(str2, s2);

        int cnt[s1.size() + 1 ][s2.size() + 1] ;
        size_t i, j;
        for(i = 0; i <= s1.size(); i++)
            for(j = 0; j <= s2.size(); j++)
            {
                if(i == 0)
                {
                    cnt[i][j] = j;
                    continue;
                }
                if(j == 0)
                {
                    cnt[i][j] = i;
                    continue;
                }
                if(s1[i-1] == s2[j-1])
                {
                    cnt[i][j] = cnt[i-1][j-1];
                }
                else
                {
                    int t1 = cnt[i-1][j-1] + 1;
                    int t2 = cnt[i][j-1] + 1;
                    int t3 = cnt[i-1][j] + 1;
                    cnt[i][j] = (t1 <= (t2 <= t3 ? t2 : t3 ) ? 
                            t1 : (t2 <= t3 ? t2 : t3));
                }
            }
        return cnt[s1.size()][s2.size()];
    }

    void str_to_vec(const string &s, vector<uint32_t> &vec)
    {
        vec.clear();
        for(string::size_type ix = 0; ix != s.size(); ix++)
        {
            int len = getlen(s[ix]);//此处的len会等于3,因为是utf-8编码,汉字占3个字节,
            if(len > 1)
            {
                uint32_t t = (unsigned char)s[ix];
                while(len > 1)
                {
                    len--;
                    t = (t << 8) + (unsigned char)s[++ix];
                }
                vec.push_back(t);
            }
        }
    }
}




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