庖丁分词的源码分析 (4) 分词过程

[size=large]庖丁分词的主要分词实现是CJKKnife,主要的方法是dissect方法。但是这个方法300多行,我不想全部贴出来。我选一些重点说说。dissect首先会用到assignable方法,其实就是找到要分词的对象,这里主要是中文。遇到不是中文的就强行截断了,后面的再继续开始。[/size]


/**
* 分解以CJK字符开始的,后可带阿拉伯数字、英文字母、横线、下划线的字符组成的语句
*/
public int assignable(Beef beef, int offset, int index) {
char ch = beef.charAt(index);
if (CharSet.isCjkUnifiedIdeographs(ch))
return ASSIGNED;
if (index > offset) {
if (CharSet.isArabianNumber(ch) || CharSet.isLantingLetter(ch)
|| ch == '-' || ch == '_') {
return POINT;
}
}
return LIMIT;
}



GO_UNTIL_LIMIT: while (true) {
switch (assignable(beef, offset, limit)) {
case LIMIT:
break GO_UNTIL_LIMIT;
case POINT:
if (point == -1) {
point = limit;
}
}
limit++;
}


如果从字典找到有:
if (curSearch.isHit()) {

if (!word.isNoise()) {
collector.collect(word.getText(), curSearchOffset,
curSearchEnd);
}
}


[size=large]把这个放到结果容器里去,当然这个容器还会再处理,就是最长和最多的分词实现,这个下篇文章会细说。
其实这个已经是分词的主要实现了,去找字典,找到的就切分出来,找不到字典的怎么办:[/size]

dissectIsolated(collector, beef, maxDicWordEnd, offsetLimit);


[size=large]
这个方法执行的就是两个字一分而已。

当然还有处理“”《》这些特殊情况的:[/size]
int len = limit - offset;
if (len > 2 && len != maxDicWordLength
&& shouldBeWord(beef, offset, limit)) {
collector.collect(beef.subSequence(offset, limit).toString(),
offset, limit);
}

[size=large]这样其实整个过程就完了,但是如何尽早确定这个词不在字典里,这个很关键,这个就用到了上篇文章说的,字典查询返回的几个状态了:[/size]
// 若isolatedFound==true,表示词典没有该词语
boolean isolatedFound = curSearch.isUndefined();

// 若isolatedFound==false,则通过Hit的next属性检视词典没有beef的从offset到curWordEnd
// + 1位置的词
// 这个判断完全是为了减少一次词典检索而设计的,
// 如果去掉这个if判断,并不影响程序的正确性(但是会多一次词典检索)
if (!isolatedFound && !curSearch.isHit()) {
isolatedFound = curSearchEnd >= limit
|| beef.charAt(curSearchEnd) < curSearch.getNext()
.charAt(curSearchLength);
}
// 2)
// 词汇表中没有该词语,且没有以该词语开头的词汇...
// -->将它记录为孤立词语
if (isolatedFound) {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值