Trie Tree 实现中文分词器
2018-07-18 11:18
537 查看
Trie Tree 简介
Trie Tree,又称单词字典树、查找树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
性质
它有3个基本性质:
根节点不包含字符,除根节点外每一个节点都只包含一个字符。
从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
每个节点的所有子节点包含的字符都不相同。
Trie Tree 结构
Trie Tree分词原理:
(1) 从根结点开始一次搜索,比如搜索【北京】;
(2) 取得要查找关键词的第一个字符【北】,并根据该字符选择对应的子树并转到该子树继续进行检索;
(3) 在相应的子树上,取得要查找关键词的第二个字符【京】,并进一步选择对应的子树进行检索。
(4) 迭代过程……
(5) 在直到判断树节点的isEnd节点为true则查找结束(最小匹配原则),然后发现【京】isEnd=true,则结束查找。
示例
下面用java简单实现
Trie Tree,又称单词字典树、查找树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。
性质
它有3个基本性质:
根节点不包含字符,除根节点外每一个节点都只包含一个字符。
从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
每个节点的所有子节点包含的字符都不相同。
Trie Tree 结构
Trie Tree分词原理:
(1) 从根结点开始一次搜索,比如搜索【北京】;
(2) 取得要查找关键词的第一个字符【北】,并根据该字符选择对应的子树并转到该子树继续进行检索;
(3) 在相应的子树上,取得要查找关键词的第二个字符【京】,并进一步选择对应的子树进行检索。
(4) 迭代过程……
(5) 在直到判断树节点的isEnd节点为true则查找结束(最小匹配原则),然后发现【京】isEnd=true,则结束查找。
示例
下面用java简单实现
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 { //记录当前节点的字 char c; //判断该字是否词语的末尾,如果是则为false boolean isEnd; //子节点 List<Node> childList; public Node(char c) { super(); this.c = c; isEnd = false; childList = new LinkedList<Node>(); } //查找当前子节点中是否保护c的节点 public Node findNode(char c){ for(Node node : childList){ if(node.c == c){ return node; } } return null; } } static class TrieTree{ Node root = new Node(' '); //构建Trie Tree public void insert(String words){ char[] arr = words.toCharArray(); Node currentNode = root; for (char c : arr) { Node node = currentNode.findNode(c); //如果不存在该节点则添加 if(node == null){ Node n = new Node(c); currentNode.childList.add(n); currentNode = n; }else{ currentNode = node; } } //在词的最后一个字节点标记为true currentNode.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; //判断是否为词的尾节点节点 if(n.isEnd){ if(n.c == arr[arr.length-1]){ return true; } } } } return false; } //最大匹配优先原则 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开始匹配的所有字 StringBuilder sb = new StringBuilder();; //最后一次匹配到的词,最大匹配原则,可能会匹配到多个字,以最长的那个为准 String word=""; //记录记录最后一次匹配坐标 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(); //记录最后一次匹配坐标 idx = i; } }else{ //判断word是否有值 if(word!=null && word.length()>0){ Integer num = map.get(word); if(num==null){ map.put(word, 1); } 5b4 else{ map.put(word, num+1); } //i回退到最后匹配的坐标 i=idx; //从root的开始匹配 currentNode = root; //清空匹配到的词 word = null; //清空当前路径匹配到的所有字 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("海淀区"); tree.insert("中国"); tree.insert("中国人民"); tree.insert("中关村"); String word = "中国"; //查找该词是否存在 Trid Tree 中 boolean flag = tree.search(word); if(flag){ System.out.println("Trie Tree 中已经存在【"+word+"】"); }else{ System.out.prin 2d90 tln("Trie Tree 不包含【"+word+"】"); } //分词 Map<String, Integer> map = tree.tokenizer("中国人民,中国首都是北京,中关村在海淀区,中国北京天安门。中国人"); for (Entry<String, Integer> entry : map.entrySet()) { System.out.println(entry.getKey()+":"+entry.getValue()); } } }
相关文章推荐
- LeetCode OJ:Implement Trie (Prefix Tree)(实现一个字典树(前缀树))
- 使用 trie tree 实现 auto-completion
- Solr下使用IK-Analyzer实现中文分词器的配置详情
- POJ_2418_Hardwood Species(map实现、Trie tree实现)
- iOS中自带超强中文分词器的实现方法
- Python学习笔记:Trie Tree的实现
- LeetCode Implement Trie (Prefix Tree) (实现trie树3个函数:插入,查找,前缀)
- 自己写中文分词器之(一)_逆向最大匹配算法的实现
- trie tree 字典树的简介与实现
- Trie (prefix tree) 实现 (Java)
- LeetCode208. Implement Trie (Prefix Tree)实现前缀树
- Trie Tree简单实现
- Trie (prefix tree) 实现 (Java)
- Trie Tree 实现中文分词器
- bitwise trie tree 的参考实现-nedtries简单解析
- [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)
- 支持中文的基于词为基本粒度的前缀树(prefix trie)python实现
- Trie Tree匹配算法实现
- HashMap实现中文分词器
- 实现字典树Trie Tree