Trie Tree 实现中文分词器

前言

继上一篇HashMap实现中文分词器后,对Trie Tree的好奇,又使用Trie Tree实现了下中文分词器。效率比HashMap实现的分词器更高。

Trie Tree 简介

Trie Tree,又称单词字典树、查找树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高。

性质

它有3个基本性质: 
1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。 
2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。 
3. 每个节点的所有子节点包含的字符都不相同。

Trie Tree 结构

Trie Tree 实现中文分词器_第1张图片

Trie Tree分词原理:

(1) 从根结点开始一次搜索,比如搜索【中国人民】; 
(2) 取得要查找关键词的第一个字符【中】,并根据该字符选择对应的子树并转到该子树继续进行检索; 
(3) 在相应的子树上,取得要查找关键词的第二个字符【国】,并进一步选择对应的子树进行检索。 
(4) 迭代过程…… 
(5) 在直到判断树节点最下面节点isEnd=true的节点,查找结束(最大匹配原则),然后发现【民】isEnd=true,则结束查找。

示例

下面用java简单实现   没有做歧义处理

package cn.com.infcn.algorithm;
 

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper;

/**
 * jijs
 * 正向最大匹配
 */
public class TireTreeQueue {
    static class Node {
        //记录当前节点的字
        char c;
        //判断该字是否词语的末尾,如果是则为false
        boolean isEnd;
        //子节点
        List childList;
 
        public Node(char c) {
            super();
            this.c = c;
            isEnd = false;
            childList = new LinkedList();
        }
 
        //查找当前子节点中是否保护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 tokenizer(String words){
            char[] arr = words.toCharArray();
            Node currentNode = root;
            //Map map = new HashMap();
            Queue queue = new LinkedList();

            //记录Trie Tree 从root开始匹配的所有字
            StringBuilder sb = new StringBuilder();;
            //最后一次匹配到的词,最大匹配原则,可能会匹配到多个字,以最长的那个为准
            String word="";
            //记录记录最后一次匹配坐标
            int idx = 0;
            for (int i=0; i0){
                        queue.offer(word);
                        //i回退到最后匹配的坐标
                        i=idx;
                      //从root的开始匹配
                      currentNode = root;
                      //清空匹配到的词
                      word = null;
                      //清空当前路径匹配到的所有字
                      sb = new StringBuilder();
                    }else {
                    	int len = sb.length();
                    	if(len > 0) {
                    		//将sb中的字放到队列中(此时sb中的字已不能组成词)
                            for(int j=0;j0){
                        Integer num = map.get(word);
                        if(num==null){
                            map.put(word, 1);
                        }else{
                            map.put(word, num+1);
                        }
                    }
                }*/

            }//for
            //
            if(word!=null && word.length()>0){
                queue.offer(word);
            }else {
                //
                int len = sb.length();
            	if(len > 0) {
                    for(int j=0;j queue = tree.tokenizer("中国人 民主");
        for (String word : queue) {
            System.out.print(word+" | ");
        }
 
    }
}

参考: https://blog.csdn.net/jijianshuai/article/details/72455736

你可能感兴趣的:(大数据)