以“南京市长江大桥”为例java
南|南京|南京市 京 市|市长 长|长江|长江大桥 江 大|大桥 桥
以每一个字为中心可拆分红如上的词列表git
构成词网github
这样计算每条路径的分数就能够知道那条路径最优了数组
计算分数的方式能够使用Ngram模型ide
代码摘自HanLP(https://github.com/hankcs/HanLP)工具
词网格对象ui
public class WordNet { /** * 节点,每一行都是前缀词,跟图的表示方式不一样 */ private LinkedList<Vertex> vertexes[]; /** * 共有多少个节点 */ int size; /** * 原始句子 * * @deprecated 应当使用数组,这样比较快 */ public String sentence; /** * 原始句子对应的数组 */ public char[] charArray; }
实现方式code
protected void GenerateWordNet(final WordNet wordNetStorage) // WordNet 词网对象 { final char[] charArray = wordNetStorage.charArray; // todo: 待研究 核心词典查询 // (Searcher是DoubleArrayTrie的查询工具 // 能够作到searcher.begin不变 searcher.length变 // 这样以某一个字开头的词能够在begin不变的状况下 变length 便可取到词) DoubleArrayTrie<CoreDictionary.Attribute>.Searcher searcher = CoreDictionary.trie.getSearcher(charArray, 0); while (searcher.next()) { wordNetStorage.add(searcher.begin + 1, new Vertex(new String(charArray, searcher.begin, searcher.length), searcher.value, searcher.index)); } // 强制用户词典查询 if (config.forceCustomDictionary) { CustomDictionary.parseText(charArray, new AhoCorasickDoubleArrayTrie.IHit<CoreDictionary.Attribute>() { @Override public void hit(int begin, int end, CoreDictionary.Attribute value) { wordNetStorage.add(begin + 1, new Vertex(new String(charArray, begin, end - begin), value)); } }); } // 原子分词,保证图连通 将英文字符等不属于汉字的字符连起来 // 由于词典当中只有汉字因此 英文字符是查不到的 没法加入词网 在这里统一处理 LinkedList<Vertex>[] vertexes = wordNetStorage.getVertexes(); for (int i = 1; i < vertexes.length; ) { if (vertexes[i].isEmpty()) { int j = i + 1; for (; j < vertexes.length - 1; ++j) { if (!vertexes[j].isEmpty()) break; } wordNetStorage.add(i, quickAtomSegment(charArray, i - 1, j - 1)); i = j; } else i += vertexes[i].getLast().realWord.length(); } }
结果对象
竟然用一个searcher工具就搞定了词网格,牛逼啊!get