目前为止,已实现了1、一维线性表 2、首字Hash 3、双Hash 三种词典的存储结构与表现形式。
首先来看一下词典结构的接口Interface:
接下来看一下一维线性表结构的词典接口实现类SimpleDictionary:
接着是首字Hash结构词典实现类HashDictionary:
基于这种结构,查询时先把字符串的首个字符作为key,若Hashtable中不包含这个key则返回false,否则取出改线性表value后使用折半查找的方法查询。
首先来看一下词典结构的接口Interface:
java 代码
/* * @作者:Hades , 创建日期:2006-11-17 * * 汕头大学03计算机本科 * */ package edu.stu.cn.segment.matching.dictionary; import java.io.PrintStream; /** * @author Hades Guan 词典操作接口 */ public interface DictionaryImpl { /** * 删除词典中的词word * * @param word * 待删除的词汇 */ public void deleteWord(String word); /** * 将词汇word插入到词典文件中 * * @param word * 待插入的词汇 */ public void insertWord(String word); /** * 载入以文本格式存储的词典 * * @param fileName * 词典的文件名 */ @SuppressWarnings("unchecked") public void loadDictionary(String fileName); /** * 判断输入的字符串是否在词典中 * * @param word * 待判断字符串 * @return 判断结果 */ public boolean match(String word); /** * 输出已载入内存中所有词汇 * * @param out * 输出流 */ public void print(PrintStream out); }
接口中定义了插入词汇、删除词汇、词汇查询、从txt文本文件中载入词典、将已载入的词典输出 五个操作。接下来看一下一维线性表结构的词典接口实现类SimpleDictionary:
java 代码
/* * @作者:Hades , 创建日期:2006-11-18 * * 汕头大学03计算机本科 * */ package edu.stu.cn.segment.matching.dictionary; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; /** * @author Hades Guan 简单顺序词典接口 */ public class SimpleDictionary implements Serializable, DictionaryImpl { /** *
SimpleDictionary类实现了自定义的DictionaryImpl接口外还实现了序列化,这样做的目的是希望能把从原始文本资料中载入的词汇排序整理后以序列化的形式写成文件,以后需要使用时直接从文件中载入就可以使用了,省去了不少初始化的麻烦。后面提到的词典实现类也都实现了序列化。serialVersionUID
的注释 */ private static final long serialVersionUID = -6631832710612755332L; /** * 词典容器 */ private ArrayList<string> dic = </string>new ArrayList<string>(); </string> /** * 删除词典中的词word * * @param word * 待删除的词汇 */ public void deleteWord(String word) { if (word == null) return; int pos; // 判断原词典中是否已有该词汇 if ((pos = Collections.binarySearch(dic, word)) < 0) return; else dic.remove(pos); } /** * 将词汇word插入到词典文件中 * * @param word * 待插入的词汇 */ public void insertWord(String word) { if (word == null) return; // 判断原词典中是否已有该词汇 if (Collections.binarySearch(dic, word) < 0) dic.add(word); // 插入后重新排序 Collections.sort(dic); } /** * 载入以文本格式存储的词典 * * @param fileName * 词典的文件名 */ public void loadDictionary(String fileName) { try { // 初始化输入流 BufferedReader in = new BufferedReader(new FileReader(fileName)); String word = null; // 读取词典 while ((word = in.readLine()) != null) { dic.add(word); } // 词典排序 Collections.sort(dic); // 关闭输入 in.close(); } catch (IOException e) { // TODO 自动生成 catch 块 e.printStackTrace(); } } /** * 判断输入的字符串是否在词典中 * * @param word * 待判断字符串 * @return 判断结果 */ public boolean match(String word) { int pos = Collections.binarySearch(dic, word); if (pos >= 0) return true; else return false; } /** * 输出已载入内存中所有词汇 * * @param out * 输出流 */ public void print(PrintStream out) { for (int i = 0; i < this.dic.size(); i++) { out.println(dic.get(i)); } out.flush(); } }
接着是首字Hash结构词典实现类HashDictionary:
java 代码
/* * @作者:Hades , 创建日期:2006-11-19 * * 汕头大学03计算机本科 * */ package edu.stu.cn.segment.matching.dictionary; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.io.PrintStream; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.Hashtable; /** * @author Hades Guan 单层哈希字典操作类 */ public class HashDictionary implements DictionaryImpl, Serializable { /** *
首字Hash结构中是使用Hashtable类作为基础,其中key为词汇的首字,如:“关心”中的“关”字,而value则是ArrayList类型的一维线性表,存储的是相同首字的词汇列表。serialVersionUID
的注释 */ private static final long serialVersionUID = -436844886894530829L; /** * 词典 */ private Hashtablenew Hashtable /** * 删除词典中的词word * * @param word * 待删除的词汇 */ public void deleteWord(String word) { if (word == null) return; // 截取首字 String fch = word.substring(0, 1); if (dic.containsKey(fch)) { // 获取词汇表 ArrayList<string> wal = dic.get(fch); </string> // 截取词汇剩余部分 String leftWord = word.substring(1); // 查找该词汇是否存在于词汇表中 int pos = Collections.binarySearch(wal, leftWord); // 存在时删除 if (pos >= 0) { wal.remove(pos); dic.put(fch, wal); } } } /** * 将词汇word插入到词典文件中 * * @param word * 待插入的词汇 */ public void insertWord(String word) { if (word == null) return; // 截取首字 String fch = word.substring(0, 1); // 词汇表 ArrayList<string> wal = null; </string> if (dic.containsKey(fch)) wal = dic.get(fch); else wal = new ArrayList<string>(); </string> // 截取词汇剩余部分 String leftWord = word.substring(1); // 判断词汇表中是否已有该词汇 if (Collections.binarySearch(wal, leftWord) < 0) { wal.add(leftWord); Collections.sort(wal); dic.put(fch, wal); } } /** * 载入以文本格式存储的词典 * * @param fileName * 词典的文件名 */ public void loadDictionary(String fileName) { try { // 初始化输入流 BufferedReader in = new BufferedReader(new FileReader(fileName)); String word = null; // 读取词典 while ((word = in.readLine()) != null) { // 插入词汇 this.insertWord(word.trim()); } } catch (IOException e) { // TODO 自动生成 catch 块 e.printStackTrace(); } } /** * 判断输入的字符串是否在词典中 * * @param word * 待判断字符串 * @return 判断结果 */ public boolean match(String word) { if (word == null) return false; // 截取首字 String fch = word.substring(0, 1); // 判断词汇表是否有此首字 if (!dic.containsKey(fch)) return false; // 获取词汇表 ArrayList<string> wal = dic.get(fch); </string> // 截取词汇剩余部分 String leftWord = word.substring(1); // 折半查找 int pos = Collections.binarySearch(wal, leftWord); return (pos >= 0); } /** * 输出已载入内存中所有词汇 * * @param out * 输出流 */ public void print(PrintStream out) { // 获取首字集合 for (String fch : dic.keySet()) { out.println("首字:" + fch); for (String w : dic.get(fch)) out.println("\t" + w); } out.flush(); } }
基于这种结构,查询时先把字符串的首个字符作为key,若Hashtable中不包含这个key则返回false,否则取出改线性表value后使用折半查找的方法查询。