📄 中文分词.txt
字号:
很久以前写的东西了,既然开新的技术博客,就全转过来吧
PHP、PERL、JAVA写的分词程序到处都是,它们使用宽字符集,字母“I”和汉字“我”在计算字长时结果是一样的,C++一般的输入都不是作为宽字符集处理的,使用C++分词,如果能完成窄字符输入,但按宽字符取子串,基本上分词的问题就解决了。(别说你取子串都按2个char算一个字啊,那样的话中英文夹杂的情况下就挂了)
下面是我本科时候写C++中文分词时写的文档,可能写得不太清楚,欢迎大家评论。
1 汉字的编码,这个主要是注意一下字典和待分词的字符串使用相同的编码就行了
2 宽字符集的转换及宽字符集字符串长度的计算
有一条关键命令是 setlocale(LC_CTYPE, "");
命令讲解:后一个参数是地区编码。如果要能正常显示宽字符集,应该正确的设置地区编码。但是我们这里要完成的工作仅仅是取子句,因此可以忽略地区编码。取子句的思路是先转换成任意编码格式的宽字符集,然后从中取子句,再转换回ASCII编码的字符串。
参考命令:
setlocale(LC_CTYPE, ""); //设置宽字符集的编码
mbstowcs(wchar_t *,const char *, size_t); //ASCII编码转宽字符集
wcstombs(char *,const wchar_t *,size_t); //宽字符集转ASCII编码
wcsncpy(wchar_t *,const wchar_t *,size_t); //宽字符集的COPY
wcslen(wchar_t *); //计算宽字符集的长度 e.g. 我是yh 宽字符集长度为4
我们写一个用于宽字符集的取子串的函数
char* subwstr(const char* myword,char* result,int from,int len)
{ //myword是原始字符串,result用来存放结果,from和len表示从myword第几个字开始取多少个字(宽字符).
wchar_t* pwstr=new wchar_t[100];
wchar_t* wcs=new wchar_t[100];
setlocale(LC_CTYPE, "");
mbstowcs(wcs, myword, 99);
wcsncpy(pwstr,wcs+from,len);
pwstr[len]='\0';
wcstombs(result, pwstr, 99);
delete[] pwstr;
delete[] wcs;
return 0;
}
到这里可以说完成了一半的工作
3 正向最大字长匹配分词
基于字典分词。字典加载进内存还是用数据库,随便。要的仅是搜索结果,即该词在字典中有没有。
思路:对一个字符串S,从前到后扫描,对扫描的每个字,从词库中寻找最长匹配.比如假设S="我是中华人民共和国公民",词库中有"中华人民共和国","中华","公民","人民","共和国"......等词.当扫描到"中"字,那么从中字开始,向后分别取1,2,3,......个字("中","中华","中华人","中华人民","中华人民共","中华人民共和","中华人民共和国",,"中华人民共和国公"),词库中的最长匹配字符串是"中华人民共和国",那么就此切分开,扫描器推进到"公"字.
4 其它词组的识别
如果前面和后面都是词组,当中间字符串长度大于1时,默认该词是一个词组。使用两个队列保存分词结果,正确匹配的词直接加入到结果队列中;另一个队列保存待分词的字符串。比如yhustc是湖南人,使用最大匹配分词,逐级减小字长,但因为字典中都无法匹配,所以前面6个字都会单独拆开,加入到待分词队列中。扫描器推进到“湖南人”,如果字典中有这个词,那么按照这里指定的规则,“湖南人”添加进结果队列,然后检查待分词队列,字长大于1,“yhustc是”也会被加入结果队列。为了提高精度,可以加入高频词筛选的功能把诸如“我”,“是”之类的词去掉。
5 输出
分词的结果保存在一个deque<string>中,只有一个字的词去掉,各种半角的标点符号全去掉,仅保留用于表示版本号的与数字结合的.,其它结果全保留,包括全角的标点符号。
6 关于字典。字典当然是越大分词精度越高,网上有一些字典下载,但词库太小,分词精度不高。我当时从拼音加加中导出了90多万个词条的一个词库,可惜不知道丢到哪去了,需要字典的朋友,自己找个词库大点的输入法导出字典吧。
测试结果
输入:腾讯QQ2006SP1.exe 字典中仅有QQ一个词,要求去掉文件名并能正确分词
输出:腾讯 QQ 2006 SP1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -