当前位置:编程学习 > C/C++ >>

C++ 处理GBK编码的汉字,计算编辑距离,以及common_prefix

我一开始就直接复制了其中的Python代码,正如我评论那篇文章的那样

这个Pytrhon代码不知道起源在在哪?P.S.网上的有太多的信息冗余,以及copied转载得文章。但是作者在转载的时候,没有check文章中的代码是否正确。 www.zzzyk.com
distance_matrix 没有初始化正确。
应该初始化为:
0,1,2,3,4
1,
2,
3,

====================================================================================================
因为要使用编辑距离,且不是Python代码中。使用的方式,可能是在shell中每次计算都要调用python xx.py string1 string2。

这样每次计算都要执行一天python命令,调用大概18000次,就需要5分钟左右。效率无法忍受。


一开始以为是计算的过程耗时,采用动态规划但是时间复杂度还是string1.length * string2.length,空间复杂度也相同。

后来采用一个简单的处理方式,就是不计算 编辑距离,而是计算common_prefix,结果发现跑18000次python命令的时间还是5分钟很长。(有时间需要研究一下,运行python xx.py的过程以及耗时)


所以,就考虑使用C++写代码。(还没有测试效率怎样)

然后,就有了上篇关于gcc 和VS 2010中分别有 sizeof(wchar_t) ==4 和 sizeof(wchar_t) == 2,使用 setlocle也没有作用。

下面就是C++处理中文的编辑距离,和common_prefix


[cpp] 
#include <iostream> 
#include <cstdlib> 
#include <cstdio> 
#include <string> 
#include <cstring> 
#include <wchar.h> 
#include <typeinfo> 
using namespace std; 
 
inline wchar_t* MBCS2Unicode(wchar_t* buff,const char * str) 

    wchar_t * wp = buff; 
    const char * p = str; 
    while(*p) 
    { 
        *wp = (wchar_t) 0x0; 
        if(*p & 0x80) 
        { 
            //因为sizeof(wchar_t) 在linux为4 
            //所以需要trick处理一下 
            char temp[sizeof(wchar_t)]; 
            temp[0] = *p; 
            p++; 
            temp[1] = *p; 
            for(int i = 2; i < sizeof(wchar_t); i++) 
                temp[i] = 0x0; 
            *wp = *(wchar_t *)temp; 
        } 
        else{ 
            *wp = (wchar_t) *p; 
        } 
        wp++; 
        p++; 
    } 
    *wp = 0x00000000; 
    return buff; 

  
inline wstring str2wstr(char* str) 

    size_t len = strlen(str); 
    wchar_t* b = (wchar_t *)malloc((len+1)*sizeof(wchar_t)); 
    MBCS2Unicode(b, str); 
    wstring r(b); 
    free(b); 
    return r; 

 
int common_prefix(const wstring& s1, const wstring& s2) { 
    int common_prefix = 0; 
    for(int i = 0, j = 0; i < s1.length() && j < s2.length() ; i++, j++) { 
        if(s1[i] == s2[j]) { 
            common_prefix++; 
        } 
        else { 
            break; 
        } 
    } 
 
    return  common_prefix; 

 
//''' 【编辑距离算法】 【levenshtein distance】 【字符串相似度算法】 ''' 
int levenshtein(const wstring& s1, const wstring& s2) { 
    if(s1.length() == 0 ) { 
        return s2.length(); 
    } 
    if(s2.length() == 0 ) { 
        return s1.length(); 
    } 
    int** distance_matrix = new int*[s1.length() + 1]; 
    for(int row = 0; row <= s1.length() ; row++ ) { 
        distance_matrix[row] = new int[s2.length() + 1]; 
        distance_matrix[row][0] = row; 
    } 
    for(int col = 0; col <= s2.length() ; col++ ) { 
        distance_matrix[0][col] = col; 
    } 
 
    for(int i = 1; i <= s1.length() ; i++ ) { 
        for(int j = 1; j <= s2.length() ; j++ ) { 
            int deletion = distance_matrix[i-1][j] + 1; 
            int insertion = distance_matrix[i][j-1] + 1; 
            int substitution = distance_matrix[i-1][j-1] + (s1[i - 1] == s2[j - 1]? 0:1); 
            distance_matrix[i][j] = min(insertion, min(deletion, substitution)); 
        } 
    } 
    for(int row = 0; row < s1.length() ; row++ ) { 
        delete[] distance_matrix[row]; 
    } 
    delete[] distance_matrix; 
 
    return distance_matrix[s1.length()][s2.length()]; 

     
int main(int argc, char* argv[]) { 
    setlocale(LC_ALL,"Chinese-simplified"); 
    if( argc != 3 ) { 
        cout << "Usage: ./common_prefix string1 string2" << endl; 
        return -1; 
    } 
 
    wstring s1 = str2wstr(argv[1]); 
    wstring s2 = str2wstr(argv[2]); 
 
    cout << common_prefix(s1, s2) << endl; 
    cout << levenshtein(s1, s2) << endl; 
    return 0; 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,