以「南京市長江大橋」爲例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