本文主要是介绍IK分词源码分析连载(四)--停用词+未切分词处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
//对分词进行歧义处理
this.arbitrator.process(context, this.cfg.useSmart());
//处理未切分CJK字符
context.processUnkownCJKChar();
//记录本次分词的缓冲区位移
context.markBufferOffset();
//输出词元
if(this.context.hasNextResult()){
return this.context.getNextLexeme();
}
- 过滤掉CHAR_USELESS字符,包括标点、无法识别的字符
- pathMap存储的是lexemePath集合,找出相邻的lexemePath,把它们之间未切分的字符逐字符输出
/**
* 处理未知类型的CJK字符
*/
void processUnkownCJKChar(){
int index = 0;
for( ; index < this.available ;){
//跳过标点符号等字符
if(CharacterUtil.CHAR_USELESS == this.charTypes[index]){
index++;
continue;
}
//从pathMap找出对应index位置的LexemePath
LexemePath path = this.pathMap.get(index);
if(path != null){
//输出LexemePath中的lexeme到results集合
Lexeme l = path.pollFirst();
while(l != null){
this.results.add(l);
//将index移至lexeme后
index = l.getBegin() + l.getLength();
l = path.pollFirst();
if(l != null){
//jw输出两个path之间没有匹配到的字符,直接单字输出
//输出path内部,词元间遗漏的单字
for(;index < l.getBegin();index++){
this.outputSingleCJK(index);
}
}
}
}else{//pathMap中找不到index对应的LexemePath
//jw没有匹配的字符,直接单字输出
//单字输出
this.outputSingleCJK(index);
index++;
}
}
//清空当前的Map
this.pathMap.clear();
}
<span style="font-family:幼圆;font-size:18px;"></span>
markBufferOffset(),这个函数就是标记buffer中的cursor指针,标明现在已经处理到哪个字符了
最后来看getNextLexeme(),从最终的分词结果集中取出分词结果,输出compound()合并数量词,将相邻的数量词切分结果进行合并
- compound()合并数量词,将相邻的数量词切分结果进行合并
- 如果取出来的词是停用词,则过滤掉,不输出
//jw这里处理数量词合并以及停用词处理
Lexeme getNextLexeme(){
//从结果集取出,并移除第一个Lexme
Lexeme result = this.results.pollFirst();
while(result != null){
//数量词合并
this.compound(result);
if(Dictionary.getSingleton().isStopWord(this.segmentBuff , result.getBegin() , result.getLength())){
//是停止词继续取列表的下一个
result = this.results.pollFirst();
}else{
//不是停止词, 生成lexeme的词元文本,输出
result.setLexemeText(String.valueOf(segmentBuff , result.getBegin() , result.getLength()));
break;
}
}
System.out.println("AnalyzeContext.java getNextLexeme result:" + result.getLexemeText());
return result;
}
上一篇 IK分词源码分析连载(三)--歧义处理
这篇关于IK分词源码分析连载(四)--停用词+未切分词处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!