中文分词一般有下面几种方法:
(http://www.googlechinablog.com/2006/04/blog-post_10.html)
1、基于字符串匹配的分词方法
1)正向最大匹配法(由左到右的方向);
2)逆向最大匹配法(由右到左的方向);
3)最少切分(使每一句中切出的词数最小)。
这几种方法一般都是通过“字典”来实现的,比如:
"中国航天官员应邀到美国与太空总署官员开会"
其中字典如下:
中国
航天
官员
。。。
这样子“流扫描”中,第一个找到“中”,不能形成词,于是再找下一个字符,凑成“中国”
把中国拿出来,扫描从“航”开始,依此类推
我想到一个问题,就是在字典中存在终结符,比如“的”,这样显然“的”就是分割词了,后面不可能合成有效词。
如何有效“查找字典”,和知道扫描达到终结符,我使用hashmap来做,如下:
比如hashmap.containsKey("中")不为空,说明下面可能存在有效词,
再次hashmap.containsKey("中国")存在结果,提取“中国”,流指针移到“航”,
同样的步骤。
代码:
类 ChineseSplit 载入中文字典
最小正向分词:buff是char[20]的数组
实现分词:
结果附图:
(http://www.googlechinablog.com/2006/04/blog-post_10.html)
1、基于字符串匹配的分词方法
1)正向最大匹配法(由左到右的方向);
2)逆向最大匹配法(由右到左的方向);
3)最少切分(使每一句中切出的词数最小)。
这几种方法一般都是通过“字典”来实现的,比如:
"中国航天官员应邀到美国与太空总署官员开会"
其中字典如下:
中国
航天
官员
。。。
这样子“流扫描”中,第一个找到“中”,不能形成词,于是再找下一个字符,凑成“中国”
把中国拿出来,扫描从“航”开始,依此类推
我想到一个问题,就是在字典中存在终结符,比如“的”,这样显然“的”就是分割词了,后面不可能合成有效词。
如何有效“查找字典”,和知道扫描达到终结符,我使用hashmap来做,如下:
比如hashmap.containsKey("中")不为空,说明下面可能存在有效词,
再次hashmap.containsKey("中国")存在结果,提取“中国”,流指针移到“航”,
同样的步骤。
代码:
类 ChineseSplit 载入中文字典
public ChineseSplit(String file) throws IOException{
InputStreamReader is;
try {
is = new InputStreamReader(new FileInputStream(file),"UTF-8");
BufferedReader buffer = new BufferedReader(is);
String tmp = null;
while( (tmp = buffer.readLine()) != null){
String[] strs = tmp.split(" ");
if(strs[0].isEmpty()||strs[0]==null||strs[1].isEmpty()||strs[1]==null){
break;
}
//System.out.println(strs[0]+" "+strs[1]);
Integer integer = new Integer(strs[1]);
wordhash.put(strs[0], integer);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
最小正向分词:buff是char[20]的数组
public int mixrightsplit(char[] buff){
System.out.println(buff);
int i=0;
int mark = 20;
while(i<20){
String taken = "";
taken = taken + buff[i];
if(wordhash.containsKey(taken)){
int lenght = (int) wordhash.get(taken);
if(lenght+i>19){
mark = i;
break;
}
int back = i+1;
String tmp = taken;
while( lenght-- > 0){
i++;
taken = taken + buff[i];
}
if(wordhash.containsKey(taken)){
i++;
}else{
taken = tmp;
i = back;
}
System.out.print(taken+" ");
}else{
System.out.print(taken+" ");
if(i==19){
mark = 19;
break;
}
i++;
}
}
System.out.print("\n");
return mark;
}
实现分词:
public void splitword(String str){
StringReader strer = new StringReader(str);
try {
char[] buff = new char[20];
int mark = 20;
while(strer.ready()){
int i=0;
while(mark<20){
buff[i]=buff[mark];
mark++;i++;
}
int read = strer.read(buff,i,20-i);
if(read<20-i&&read!=-1){
for(i=read;i<20;i++){
buff[i] = ' ';
}
mark = mixrightsplit(buff);
break;
}
mark = mixrightsplit(buff);
}
} catch (IOException e) {
e.printStackTrace();
}
}
结果附图: