今天纠结了一天,还是把这个弄出来了!太有成就感了……呵呵
首先得把IK_Analyzer的jar包放到项目中,然后“当前project”->properities->java build path->add jar 把IKAnalyzer3.2.5Stable.jar增加进去。我用的是这个版本的 嘻嘻!
现在就可以开始写代码了!我的做法是先看NGramTokenizer的源代码,然后依葫芦画瓢就可以了!
不过,画瓢之前呢,还是有必要了解一个IKAnalyzer是怎么分词的,不废话了,直接上分词的代码吧:
- package com.xh;
- import java.io.IOException;
- import java.io.StringReader;
- import org.wltea.analyzer.IKSegmentation;
- import org.wltea.analyzer.Lexeme;
- public class Segment {
- public static void main(String[] args)
- {
- IKSegmentation seg=null;
- String text = "苏轼不是圣人,他最可贵的地方是在痛苦彷徨挣扎中," +
- "总能把自己的心灵置于更广阔的天地中,如同《赤壁后赋》中横飞而去的老鹤," +
- "戛戛于星空夜月,长河大江之上,澄明清澈,皎然不滓。" +
- "苏轼是一个善于苦中找乐的人,这种乐观与真趣帮他度过了不少难关。" +
- "画家陈丹青说鲁迅是一个有趣的人,我想,拿来说苏东坡一样也行。";
- StringReader reader=new StringReader(text);
- seg=new IKSegmentation(reader);
- Lexeme lex=new Lexeme(0, 0, 0, 0);
- try {
- while((lex=seg.next())!=null)
- {
- System.out.print(lex.getLexemeText() + "|");
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
如果看不明白,可以看一下IKAnalyzer的api,在我上传的资源中有,直接在51cot里搜索就可以找到了!
看明白IKAnalyzer是怎么分词后,我们就可以把它跟wvtool结合了,毕竟wvtool的分词不是真正意义上的分词!好了,贴代码吧,尽管我不喜欢很多博客一打开全是代码,但我自己确实也讲不太明白,可能代码能更直白吧:
- package com.xh;
- import java.io.IOException;
- import java.io.Reader;
- import java.io.StringReader;
- import java.util.ArrayList;
- import java.util.List;
- import org.wltea.analyzer.IKSegmentation;
- import org.wltea.analyzer.Lexeme;
- import edu.udo.cs.wvtool.generic.tokenizer.SimpleTokenizer;
- import edu.udo.cs.wvtool.generic.tokenizer.WVTTokenizer;
- import edu.udo.cs.wvtool.main.WVTDocumentInfo;
- import edu.udo.cs.wvtool.util.TokenEnumeration;
- import edu.udo.cs.wvtool.util.WVToolException;
- /*
- * 这个程序是wvtool结合IKAnalyzer的分词而写成的分词代码,
- * 程序执行的速度有些慢,由于我也是初学,对于其中的原理也
- * 不甚明了,仅供大家做个参考而已
- * */
- public class IKAnalyzerTokenizer implements WVTTokenizer,TokenEnumeration{
- /*
- * 一般用Wvtool进行分词的时候,我们都习惯传入SimpleTokentizer,而SimpleTokenizer
- * 好像只是提取出了一行文本,根本就没有分词,
- * 而这里面,应该是对文本:一行一行的进行分词
- * 而且真正实现分词功能的代码在readTokenizer()方法中,这个方法也是这个类里
- * 唯一的私有方法
- * */
- private final List<String> currentToken;
- private TokenEnumeration enumeration;
- private final WVTTokenizer tokenizer;
- public IKAnalyzerTokenizer(WVTTokenizer tokenizer){
- this.tokenizer=tokenizer;
- currentToken=new ArrayList<String>();
- enumeration=null;
- }
- @Override
- public TokenEnumeration tokenize(Reader source, WVTDocumentInfo info)
- throws WVToolException {
- if(source!=null){
- //刚开始看到这段代码,我以为是递归,后来发现跟本不是的,这里它调用的是通过构造函数
- //传过来的对象的方法,而不是本方法
- enumeration=tokenizer.tokenize(source, info);
- readNextTokenizer();
- return this;
- }else{
- return null;
- }
- }
- @Override
- public boolean hasMoreTokens() {
- if (enumeration != null)
- return (currentToken.size() > 0);
- else
- return false;
- }
- @Override
- public String nextToken() throws WVToolException {
- String result = null;
- // If unequal null, return the current token and read another one from
- // the stream
- if (currentToken.size() > 0) {
- result = (String) currentToken.get(0);
- currentToken.remove(0);
- if (currentToken.size() == 0)
- readNextTokenizer();
- } else
- result = null;
- return result;
- }
- private void readNextTokenizer() throws WVToolException{
- //我想吧:真正影响程序性能的代码在这里……但怎么优化呢?唉! 我也不知道啦……
- if(enumeration.hasMoreTokens()){
- //其实吧:就是读入一行文本
- String string=enumeration.nextToken();
- //包装一下吧
- StringReader reader=new StringReader(string);
- //好了,分词在这里完成
- IKSegmentation seg=new IKSegmentation(reader);
- Lexeme lex=new Lexeme(0, 0, 0, 0);
- try {
- while((lex=seg.next())!=null)
- {
- currentToken.add(lex.getLexemeText());
- }
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- //最后测试一下吧
- public static void main(String[] args) throws WVToolException {
- IKAnalyzerTokenizer toker=new IKAnalyzerTokenizer(new SimpleTokenizer());
- String string="雅虎新闻雅虎新闻并校十年难言成败\n雅虎新闻雅虎新闻并校十年难言成败";
- StringReader reader=new StringReader(string);
- WVTDocumentInfo info=new WVTDocumentInfo("text.html", "html", "utf-8", "chinese");
- TokenEnumeration enumeration=toker.tokenize(reader, info);
- while(enumeration.hasMoreTokens()){
- System.out.print(enumeration.nextToken()+"|");
- }
- //结果:雅虎|新闻|雅虎|新闻|并|校|十年|十|年|难言|成败|雅虎|新闻|雅虎|新闻|并|校|十年|十|年|难言|成败|
- }
- }
其实吧,我只是在readTokenzer方法中加入了分词,其它都没变!