zoukankan      html  css  js  c++  java
  • TSE中关于分词的算法的改写最少切分

    今天比较闲,想到以前也看了好多tse的代码,还没有上手改过呢,一时也不知从何入手,后来在书上看到了分词的算法,TSE用的是正向最大匹配,其中貌似有个好玩的算法-----最少切分,捣鼓了一下午,终于把代码弄出来了。

    如果有人有兴趣的话,在HzSeg中修改SegmentSentenceMM函数的代码,将s2+=SegmentHzStrMM(dict, s1.substr(0,i));

    改成s2+=SegmentHzStr_min_cut(dict, s1.substr(0,i));就OK了。

    代码显得还是有些冗余,还是有优化的余地的,有时间再改吧。

     1 string get_res(map<int,map<int,int> > path,    map<int,int>  min_path,string s1,int l){
     2 #undef _debug_hzseg
     3 #ifdef _debug_hzseg
     4     cout<<"s1:"<<s1<<"l"<<l<<endl;
     5     for (int i = 0; i < l; i++) {
     6         cout<<"<!-- ";
     7         for (int j = 0; j < l; j++) {
     8             cout<<path[i][j]<<" ";
     9         }
    10         cout<<"-->"<<endl;
    11     }
    12     for (int i = 0; i < l; i++) {
    13         cout<<min_path[i];
    14     }
    15 #endif
    16     int i,j,start,next_start,tmp_min;
    17     string res;
    18     start=0;
    19     while(start<l){
    20         tmp_min=min_path[start];
    21         for(j=start;j<l-1;j++){
    22             if((1==path[start][j])&&tmp_min==path[start][j]+min_path[j+1]){//如果这个是最少切分的话,就记录下来
    23                 res=res+s1.substr(start*2,j*2-start*2+2)+SEPARATOR;
    24                 start=j+1;
    25                 break;
    26             }
    27         }
    28         if ((1==path[start][j])&&j == l-1 ) {
    29             res = res + s1.substr(start * 2, j * 2 - start * 2 +2) + SEPARATOR;//说明是最后一个了
    30             start=l;
    31             break;
    32         }
    33     }
    34 return res;
    35 }
    36 
    37 
    38 
    39 // 最小切分算法
    40 string SegmentHzStr_min_cut (CDict &dict, string s1)
    41 {
    42     int j;
    43     int s1_size=s1.size()/2;
    44     string tmp;
    45     map<int,map<int,int> > path;
    46     map<int,int>  min_path;
    47     bool isw;
    48 
    49     for (int i = 0; i < s1_size; i++) {
    50         for (int j = 0; j < s1_size; j++) {
    51                 path[i][j] = 0;
    52         }
    53     }
    54 
    55     for(int i=0;i<s1_size;i++){
    56         for(int j=i;j<s1_size;j++){
    57             tmp=s1.substr(i*2,j*2-i*2+2);
    58             isw=dict.IsWord(tmp);
    59             if(isw)
    60                 path[i][j]=1;
    61         }
    62     }
    63     for(int i=0;i<s1_size;i++)
    64         path[i][i]=1;//每个单独的字认为是一个词
    65 
    66     map<int,int> min_cut;
    67     min_path[s1_size-1]=1;
    68     for(int i=s1_size-2;i>=0;i--){//动态规划做的
    69         min_path[i]=10000;
    70         for(j=i;j<s1_size-1;j++){
    71             if(1==path[i][j]&&(min_path[i]>path[i][j]+min_path[j+1])){
    72                     min_path[i]=path[i][j]+min_path[j+1];
    73             }
    74         }
    75         if (path[i][j] ) {
    76             min_path[i] = 1;
    77         }
    78     }
    79     string s2=get_res(path,min_path,s1,s1_size);//根据上边算出来的min_path获得最少切分
    80     return s2;
    81 }
  • 相关阅读:
    Java多线程学习(吐血超具体总结)
    java.lang.Integer can not be cast to java.lang.Long
    【转】随身HiFi 安卓OTG功能在音频上的妙用
    【转】锋狂百科:手机也能接外设 OTG技术详解
    【转】用串口登录Beaglebone Black、用usb共享电脑网络、内核模块的本地编译
    【转】Beagleboard:BeagleBoneBlack
    【转】
    【转】Beaglebone Black
    【转】你应该知道的 10 个 VirtualBox 技巧与高级特性
    如何把SKYPE的发送消息由enter改为ctrl+enter?
  • 原文地址:https://www.cnblogs.com/kakamilan/p/2623444.html
Copyright © 2011-2022 走看看