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 }
posted on 2012-08-04 22:20 kakamilan 阅读(1506) 评论(0) 编辑 收藏 举报