论坛首页 Java企业应用论坛

中文分词小程序(源码下载)

浏览 3190 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-04-08   最后修改:2009-07-20
1.接口
定义一个接口 Cut ,并实现 java.io.Serializable

然后用抽象类 AbstractCut 实现 Cut 接口,所以 AbstractCut 子类可以实现对象序列化操作

2.抽象
MaxRightCut(最大向右分词) 和 MaxleftCut (最大向左分词) 继承 AbstractCut

3.实现
MaxRightCut 和 MaxleftCut 分别实现了AbstractCut 的抽象方法 abstract DLLNode cut(Set set, String doc);

4.组合
定义类 CutManager 具有两个属性,Cut(能使用分词方法) 和 Set(词典集合)

关于词典、HashSet(散射表);预先序列化成二进制文件、使用它就进行反序列化

主要以对象序列化的方式,实现分词方法和词典的替换


5.界面
界面操作、主要用swing技术。CutFrame 继承javax.swing.JFrame

CutFrame 具有属性 CutManager ,操作 CutManager 中的 Cut 接口提供的方法、进行分词


1.接口
定义一个接口 Cut ,并实现 java.io.Serializable
package com.cut.util;

import java.util.Set;

public interface Cut extends java.io.Serializable{
	public String doCut(Set set,String doc) ;
}



然后用抽象类 AbstractCut 实现 Cut 接口,所以 AbstractCut 子类可以实现对象序列化操作,并定义了一个未实现的抽象方法cut(Set set, String doc)
package com.cut.util.cut;

import java.util.Set;
import com.cut.util.Cut;

public abstract class AbstractCut implements Cut {


	/**
	 * 
	 */
	private static final long serialVersionUID = 6243250356503179429L;
	StringBuffer newDoc = new StringBuffer(" ");
	

	// 分词算法,待实现
	protected abstract DLLNode cut(Set set, String doc);
	
	
	public String doCut(Set hashSet, String doc) {
		// TODO Auto-generated method stub
	
		// 最大向右分词
		
		long t1=System.nanoTime();
		DLLNode qs=cut(hashSet, doc);
		long t2=System.nanoTime();
		System.out.println("分词效率:"+(t2-t1));
		//生成新doc
		doDoc(qs);
		String temp = newDoc.toString();
		//清除属性 newDoc的字符串,下次使用
		clear();
		return temp;
	}
	
	//生成新doc
	private void doDoc(DLLNode link) {
		while(link!=null){
			String word = (String) link.data;
			if (isAddtSpaces(newDoc, word)) {
				newDoc.append(" " + word);
			} else {
				newDoc.append(word);
			}
			link=link.next;
		}
	}

	
	// 向左 添加单词,是否要添加空格
	private boolean isAddtSpaces(StringBuffer newDoc, String word) {
		// 获取新单词的(首)字符
		char flag1 = word.charAt(0);
		// 获取旧单词的(尾)字符
		char flag2 = newDoc.charAt(newDoc.length() - 1);

		// 如果同为数字或字母,则新单词与旧单词之间不用空格
		if (isDigit(flag1) && isDigit(flag2)
				|| isLetter(flag1) && isLetter(flag2)) {
			return false;
		}else {
			return true;
		}
	}

	// 是否是数字
	private boolean isDigit(char c) {
		if (c >= '0' && c <= '9') {
			return true;
		} else {
			return false;
		}
	}

	// 是否是字母
	private boolean isLetter(char c) {
		if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
			return true;
		} else {
			return false;
		}
	}

	// 清除 newDoc
	private void clear() {
		newDoc.delete(1, newDoc.length());
	
	}
	
	//节点类
	protected class DLLNode {

		  Object data;   // the data wrapped in the node
		  DLLNode prev;  // reference to the previous Node
		  DLLNode next;  // reference to the next Node

		  // default constructor,empty node
		  public DLLNode() {}

		  // constructor for node with given object 
		  public DLLNode(Object obj) { data = obj; }

		  // general constructor
		  public DLLNode(Object obj, DLLNode prevLink, DLLNode nextLink) {    
		    data = obj;
		    prev = prevLink;
		    next = nextLink; 
		  }

		public String toString()
		  { return data.toString(); }
		}

}



3.实现
MaxleftCut 分别实现了AbstractCut 的抽象方法 abstract DLLNode cut(Set set, String doc);

package com.cut.util.cut;

import java.util.Set;

public class MaxleftCut extends AbstractCut {


	/**
	 * 
	 */
	private static final long serialVersionUID = -1107138974220147102L;

	// 最大向右分词
	public DLLNode cut(Set set, String doc) {
		// Queue queue=new ArrayQueue();
		DLLNode cur = new DLLNode(" ");

		// 最大词长
		int wordLength = 7;
		// 将要进行切词的字符串的长度
		int len = doc.length();
		// 两次循环进行切词

		for (int right = len; right > 0; right--) {
			for (int left = right - wordLength; left < len; left++) {
				if (left <0) {
					left = 0;
				}
				String word = doc.substring(left, right);
				if (set.contains(word)) {
					cur.prev = new DLLNode(word);
					cur.prev.next = cur;
					cur = cur.prev;
					right = left+1;
					break;
				} else if (right - left == 1) {
					cur.prev = new DLLNode(word);
					cur.prev.next = cur;
					cur = cur.prev;
					break;
				}

			}
		}
		return cur;
	}

}



3.实现
MaxRightCut实现了AbstractCut 的抽象方法 abstract DLLNode cut(Set set, String doc);
package com.cut.util.cut;
import java.util.Set;
public class MaxRightCut extends AbstractCut {
	

	/**
	 * 
	 */
	private static final long serialVersionUID = -4574704989104601717L;

	//最大向右分词
	protected DLLNode cut(Set set,String doc) {
		//Queue queue=new ArrayQueue();
		DLLNode cur=new DLLNode(" ");
		DLLNode head=cur;
		
		//最大词长
		int wordLength = 7;
		//将要进行切词的字符串的长度
		int len=doc.length();
		//两次循环进行切词
		for (int left = 0; left < len; left++) {
			for (int right = left + wordLength; right > left; right--) {
				if (right > len) {
					right = len;
				}
				String word = doc.substring(left, right);
				if (set.contains(word)) {
					cur.next=new DLLNode(word);
					cur=cur.next;
					left = right - 1;
					break;
				} else if (right-left == 1) {
					cur.next=new DLLNode(word);
					cur=cur.next;
					break;
				}
				
			}
		}
		return head;
	}
	
}




4.组合
定义类 CutManager 具有两个属性,Cut(能使用分词方法) 和 Set(词典集合)
package com.cut.main;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Set;

import com.cut.util.Cut;

public class CutManager {

	public CutManager() {
		set = (Set) dodeserialize("serialize//搜狗词典.dat");
		cut=(Cut)dodeserialize("serialize//最大向左.dat");
	}
	private Cut cut;
	private Set set;
	
	public String doCut(String doc) {
		return cut.doCut(set, doc);
	}

	// 选择词典
	public void SelecteSet(String name) {
		set = (Set) dodeserialize("serialize//" + name + ".dat");

	}

	// 选择分词方法
	public void SelecteCut(String name) {
		cut = (Cut) dodeserialize("serialize//" + name + ".dat");
	}

	// 进行对象序列化
	public void doSerialize(Object o, String URL) {
		try {

			FileOutputStream outFile = new FileOutputStream(URL);
			ObjectOutputStream outStream = new ObjectOutputStream(outFile);
			outStream.writeObject(o);
			outStream.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// 反序列化
	public Object dodeserialize(String URL) {
		Object o = null;
		try {
			FileInputStream inFile = new FileInputStream(URL);
			ObjectInputStream inStream = new ObjectInputStream(inFile);
			o = inStream.readObject();
			inStream.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return o;
	}

}

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics