日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Trie Tree 实现中文分词器

發(fā)布時(shí)間:2024/9/30 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Trie Tree 实现中文分词器 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

繼上一篇HashMap實(shí)現(xiàn)中文分詞器后,對(duì)Trie Tree的好奇,又使用Trie Tree實(shí)現(xiàn)了下中文分詞器。效率比HashMap實(shí)現(xiàn)的分詞器更高。

Trie Tree 簡(jiǎn)介

Trie Tree,又稱單詞字典樹(shù)、查找樹(shù),是一種樹(shù)形結(jié)構(gòu),是一種哈希樹(shù)的變種。典型應(yīng)用是用于統(tǒng)計(jì)和排序大量的字符串(但不僅限于字符串),所以經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計(jì)。它的優(yōu)點(diǎn)是:最大限度地減少無(wú)謂的字符串比較,查詢效率比哈希表高。

性質(zhì)

它有3個(gè)基本性質(zhì):
1. 根節(jié)點(diǎn)不包含字符,除根節(jié)點(diǎn)外每一個(gè)節(jié)點(diǎn)都只包含一個(gè)字符。
2. 從根節(jié)點(diǎn)到某一節(jié)點(diǎn),路徑上經(jīng)過(guò)的字符連接起來(lái),為該節(jié)點(diǎn)對(duì)應(yīng)的字符串。
3. 每個(gè)節(jié)點(diǎn)的所有子節(jié)點(diǎn)包含的字符都不相同。

Trie Tree 結(jié)構(gòu)

Trie Tree分詞原理:

(1) 從根結(jié)點(diǎn)開(kāi)始一次搜索,比如搜索【北京】;
(2) 取得要查找關(guān)鍵詞的第一個(gè)字符【北】,并根據(jù)該字符選擇對(duì)應(yīng)的子樹(shù)并轉(zhuǎn)到該子樹(shù)繼續(xù)進(jìn)行檢索;
(3) 在相應(yīng)的子樹(shù)上,取得要查找關(guān)鍵詞的第二個(gè)字符【京】,并進(jìn)一步選擇對(duì)應(yīng)的子樹(shù)進(jìn)行檢索。
(4) 迭代過(guò)程……
(5) 在直到判斷樹(shù)節(jié)點(diǎn)的isEnd節(jié)點(diǎn)為true則查找結(jié)束(最小匹配原則),然后發(fā)現(xiàn)【京】isEnd=true,則結(jié)束查找。

示例

下面用java簡(jiǎn)單實(shí)現(xiàn)

package cn.com.infcn.algorithm;import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry;/*** jijs* 正向最大匹配*/ public class TrieTreeDemo {static class Node {//記錄當(dāng)前節(jié)點(diǎn)的字char c;//判斷該字是否詞語(yǔ)的末尾,如果是則為falseboolean isEnd;//子節(jié)點(diǎn)List<Node> childList;public Node(char c) {super();this.c = c;isEnd = false;childList = new LinkedList<Node>();}//查找當(dāng)前子節(jié)點(diǎn)中是否保護(hù)c的節(jié)點(diǎn)public Node findNode(char c){for(Node node : childList){if(node.c == c){return node;}}return null;}}static class TrieTree{Node root = new Node(' ');//構(gòu)建Trie Treepublic void insert(String words){char[] arr = words.toCharArray();Node currentNode = root;for (char c : arr) {Node node = currentNode.findNode(c);//如果不存在該節(jié)點(diǎn)則添加if(node == null){Node n = new Node(c);currentNode.childList.add(n);currentNode = n;}else{currentNode = node;}}//在詞的最后一個(gè)字節(jié)點(diǎn)標(biāo)記為truecurrentNode.isEnd = true;}//判斷Trie Tree中是否包含該詞public boolean search(String word){char[] arr = word.toCharArray();Node currentNode = root;for (int i=0; i<arr.length; i++) {Node n = currentNode.findNode(arr[i]);if(n != null){currentNode = n;//判斷是否為詞的尾節(jié)點(diǎn)節(jié)點(diǎn)if(n.isEnd){if(n.c == arr[arr.length-1]){return true;}}}}return false;}//最大匹配優(yōu)先原則public Map<String, Integer> tokenizer(String words){char[] arr = words.toCharArray();Node currentNode = root;Map<String, Integer> map = new HashMap<String, Integer>();//記錄Trie Tree 從root開(kāi)始匹配的所有字StringBuilder sb = new StringBuilder();;//最后一次匹配到的詞,最大匹配原則,可能會(huì)匹配到多個(gè)字,以最長(zhǎng)的那個(gè)為準(zhǔn)String word="";//記錄記錄最后一次匹配坐標(biāo)int idx = 0;for (int i=0; i<arr.length; i++) {Node n = currentNode.findNode(arr[i]);if(n != null){sb.append(n.c);currentNode = n;//匹配到詞if(n.isEnd){//記錄最后一次匹配的詞word = sb.toString();//記錄最后一次匹配坐標(biāo)idx = i;}}else{//判斷word是否有值if(word!=null && word.length()>0){Integer num = map.get(word);if(num==null){map.put(word, 1);}else{map.put(word, num+1);}//i回退到最后匹配的坐標(biāo)i=idx;//從root的開(kāi)始匹配currentNode = root;//清空匹配到的詞word = null;//清空當(dāng)前路徑匹配到的所有字sb = new StringBuilder();}}if(i==arr.length-2){if(word!=null && word.length()>0){Integer num = map.get(word);if(num==null){map.put(word, 1);}else{map.put(word, num+1);}}}}return map;}}public static void main(String[] args) {TrieTree tree = new TrieTree();tree.insert("北京");tree.insert("海淀區(qū)");tree.insert("中國(guó)");tree.insert("中國(guó)人民");tree.insert("中關(guān)村");String word = "中國(guó)";//查找該詞是否存在 Trid Tree 中boolean flag = tree.search(word);if(flag){System.out.println("Trie Tree 中已經(jīng)存在【"+word+"】");}else{System.out.println("Trie Tree 不包含【"+word+"】");}//分詞Map<String, Integer> map = tree.tokenizer("中國(guó)人民,中國(guó)首都是北京,中關(guān)村在海淀區(qū),中國(guó)北京天安門。中國(guó)人");for (Entry<String, Integer> entry : map.entrySet()) {System.out.println(entry.getKey()+":"+entry.getValue());}} }

想了解更多精彩內(nèi)容請(qǐng)關(guān)注我的公眾號(hào)

本人簡(jiǎn)書(shū)blog地址:http://www.jianshu.com/u/1f0067e24ff8????
點(diǎn)擊這里快速進(jìn)入簡(jiǎn)書(shū)

GIT地址:http://git.oschina.net/brucekankan/
點(diǎn)擊這里快速進(jìn)入GIT

總結(jié)

以上是生活随笔為你收集整理的Trie Tree 实现中文分词器的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。