中英文字典树_字典树详解

中英文字典树_字典树详解英文字典树英文字典树的结构图是这样的。按照树型结构存储字符串,每个结点存一个字符,自顶向下做标记的就是词的词尾,比如,app,apple,application,abstract,absorb,block,black,blake…等等介绍一下英文字典树的结点数据结构:1.词频int型变量记录词频2.结点型数组,长度26下标对应0-25(也…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

英文字典树

    英文字典树的结构图是这样的。按照树型结构存储字符串,每个结点存一个字符,自顶向下做标记的就是词的词尾,比如,app,apple,application,abstract,absorb,block,black,blake… 等等

    介绍一下英文字典树的结点数据结构:

        1.词频 int型变量记录词频

        2.结点型数组,长度26下标对应0 – 25(也就是当前字符 ‘ ? ‘ –  ‘ a ‘ 用字符ASCII码做运算,值域 0 – 25)

        3.flag标记,当前结点是否构成单词        

        4.结点值        

    中英文字典树_字典树详解

中文字典树:

     结构和英文字典树相似,但是因为中文的原因,我们没有使用数组,用字符+-的方式来计算显然不行了。所以这里我用的hashmap存的下一位的孩子们。

      看一下中文字典树的图:

       中英文字典树_字典树详解

    数据结构:

        public Integer frequency;    //词频
        public Boolean isWords;      //是否是词
        public Character values;        //值
        public HashMap<String,TrieNode> childNodes ;    //孩子们

   插入:

          拿到一个词,拆开,从词的第一个字开始找,找到了就拿第二个字继续往下找,找不到拿当前做比较的字开辟结点。

          插入时注意好维护每个结点的词频,而且还要看是否是最后一个字,插入最后一个字的时候要标记当前字为词结点。

    查找:

          也就是拿词拆开,挨个比较,找到了就输出并返回true。

    删除词:

          在找词的过程中把孩子 > 1的结点压入栈,找到词后把栈顶元素和当前词相关的元素抹去就ok了。

中英文字典树_字典树详解  中英文字典树_字典树详解

中文字典树源代码:

package com.cccl.datastruct.Tree.tiretree;

import com.cccl.datastruct.queue.MyLinkedQueue;

import java.util.*;

public class Trie {

    private static Integer[] level = { 1,0,0,0, 0,0,0,0 }; //trie树 词应该不会超过8的长度   树也最高也就五六层  词语

    private TrieNode trieRoot;
    public Trie(){
        trieRoot = new TrieNode();
        trieRoot.frequency = 0;
    }

    /**
     * 插入中文词组
     * @param data
     * @return
     */
    public Boolean insert(String data){
        ArrayList<String> arrays =  toStringArrays(data);
        TrieNode point = trieRoot;
        TrieNode nextChild = null;
        String nowArraysStr = "";
        for (int i = 0; i < arrays.size(); i++) {
            point.frequency++;
            nowArraysStr = arrays.get(i);
            nextChild = point.childNodes.get(nowArraysStr);
            if (nextChild == null){
                TrieNode addTire = new TrieNode(nowArraysStr.charAt(0));
                if (i == arrays.size()-1){
                    addTire.isWords = true;
                    addTire.frequency = 1;
                    point.childNodes.put(nowArraysStr,addTire);
                    level[i+1]++;
                    break;
                }
                point.childNodes.put(nowArraysStr,addTire);
                level[i+1]++;
                point = addTire;
            }else {
                point = nextChild;
            }
        }
        return true;
    }

    /**
     * 查询词组
     * @param data
     * @return
     */
    public Boolean searchWords(String data){
        ArrayList<String> arrays =  toStringArrays(data);
        TrieNode point = trieRoot;
        TrieNode nextChild = null;
        String s = "";
        for (int i = 0; i < arrays.size(); i++) {
            nextChild = point.childNodes.get(arrays.get(i));
            if (nextChild == null){
                return false;
            }else {
                point = nextChild;
                showPointInfo(point);
                s += point.values;
            }
        }
        System.out.println(s);
        return true;
    }


    /**
     * 查询前缀词频
     * @param data
     * @return
     */
    public boolean searchPreWord(String data){
        ArrayList<String> arrays =  toStringArrays(data);
        TrieNode point = trieRoot;
        TrieNode nextChild = null;
        String s = "";
        for (int i = 0; i < arrays.size(); i++) {
            nextChild = point.childNodes.get(arrays.get(i));
            if (nextChild == null){
                System.out.println("没有此前缀!");
                return false;
            }else {
                point = nextChild;

            }
        }
        showPointInfo(point);
        return true;
    }

    /**
     * 层序遍历trie树
     */
    public void showTrieTree(){
        TrieNode point = trieRoot;
        MyLinkedQueue<TrieNode> queue = new MyLinkedQueue<TrieNode>();
        queue.enQueue(point);
        Integer lev = 0;
        Integer count = 0;
        while (queue.getCount()>0){
            TrieNode trieNode = queue.deQueue();
            Collection<TrieNode> childs = trieNode.childNodes.values();
            Iterator<TrieNode> iterator = childs.iterator();
            while (iterator.hasNext()){
                queue.enQueue(iterator.next());
            }
            System.out.print(trieNode.values + "  ");
            count++;
            if (count == level[lev]){
                System.out.println();
                lev++;
                count = 0;
            }
        }
    }

    /**
     * 主函数
     * @param args
     */
    public static void main(String[] args) {
        String[] strings = {"天天向上","天人合一","天天学习","我是大神","快马加鞭"};
        Trie trie = new Trie();
        for (String s:
                strings) {
            trie.insert(s);
        }
        //  trie.searchWords("天天向上");
        // trie.searchPreWord("天天");
        trie.showTrieTree();
    }

    public class TrieNode {

        public TrieNode(){
            childNodes = new HashMap<String,TrieNode>(8);
            isWords = false;
            frequency = 0;
            values = '根';
        }
        public TrieNode(Character data) {
            childNodes = new HashMap<String,TrieNode>(8);
            isWords = false;
            frequency = 0;
            values = data;
        }

        public Integer frequency;
        public Boolean isWords;
        public Character values;
        public HashMap<String,TrieNode> childNodes ;

        @Override
        public String toString() {
            return "TrieNode{" +
                    "frequency=" + frequency +
                    ", isWords=" + isWords +
                    ", values=" + values +
                    ", childNodes=" + childNodes.toString() +
                    '}'+'\n';
        }
    }

    private void showPointInfo(TrieNode point){
        System.out.println("当前  结点值:" + point.values);
        System.out.println("当前结点词频:" + point.frequency);
        System.out.print("当前结点孩子:");
        Set<String> chs = point.childNodes.keySet();
        Iterator<String> iterator = chs.iterator();
        while (iterator.hasNext()){
            System.out.print(" " + iterator.next());
        }
        System.out.println();
    }

    private static ArrayList<String> toStringArrays(String data){
        ArrayList<String> result = new ArrayList<String>(data.length());
        for (int i = 0; i < data.length(); i++) {
            result.add("" + data.charAt(i));
        }
        return result;
    }

    @Override
    public String toString() {
        return "Trie{" +
                "trieRoot=" + trieRoot.toString() +
                '}';
    }
}

因为层序遍历用到了队列,队列代码:

package com.cccl.datastruct.queue;

/**
 * Created by 小H on 2018/3/21.
 */
public class MyLinkedQueue<T> {


    public Node<T> front = null;
    public Node<T> rear = null;
    private Integer count = 0;
    public Integer getCount() {
        return count;
    }
    public MyLinkedQueue(){
        initQueue();
    }

    /**
     * 初始化队列
     */
    private void initQueue(){
        front = new Node<T>();
        rear = front;
    }

    /**
     * 销毁队列
     */
    public void destroyQueue(){
        front = null;
        rear = null;
    }

    /**
     * 入队
     * @param data
     * @return
     */
    public boolean enQueue(T data){
        try {
            Node<T> node = new Node<T>(data);
            node.pre = rear;
            rear.next = node;
            rear = rear.next;
            count++;
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 出队
     * @return
     */
    public T deQueue(){
        try {
            if(front == rear) {
                System.out.println("没有元素了,不能出队了");
                return null;
            }
            front = front.next;
            count--;
            return front.data;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 返回队头元素
     * @return
     */
    public T getQueue(){
        try {
            if(front == rear) {
                System.out.println("没有元素了,不能找到队头元素了");
                return null;
            }
            return front.next.data;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }

    private static class Node<T>{
        public Node<T> pre = null;
        public Node<T> next = null;
        public T data = null;
        public Node(){}
        public Node(T d){
            data = d;
        }
    }



}

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196549.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 备份数据库的存储过程.sql

    备份数据库的存储过程.sql

  • 一款自制的视频录制软件

    一款自制的视频录制软件是利用opencv库的,平时自己需要录制东西,但是网上大部分的软件只录制屏幕,不能录制摄像头视屏,所以自己动手弄了个不是特别好用,但也讲究这凑合程序源代码:http://download.csdn.net/source/3578833

  • Linux之traceroute命令[通俗易懂]

    Linux之traceroute命令[通俗易懂]显示数据包到主机间的路径,traceroute命令用于追踪数据包在网络上的传输时的全部路径,它默认发送的数据包大小是40字节。通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径。当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一样,但基本上来说大部分时候所走的路由是相同的。traceroute通过发送小的数据包到目的设备直到其返回,来测量其需要多长时间。一条路径上的每个设备traceroute要测.

  • go 数据处理_2018毛概第十二章重点

    go 数据处理_2018毛概第十二章重点gocn_news_2018-12-311.Go入门简介:http://t.cn/EbjzeSt 2.GoGraphQL新手指南:https://tutorialedge.net/golang/go-graphql-beginners-tutorial/ 3.你需要Goweb框架吗:https://medium.com/@tusharsoni/do-you-need-a-web-framework-for-go-51171bb0ea8c 4.OpenEdge:开放的边缘计算平

  • 重定向和转发的区别及应用_重定向发给别人能看见吗

    重定向和转发的区别及应用_重定向发给别人能看见吗重定向和转发的区别:一:重定向与转发的区别1.重定向过程:客户端浏览器发送http请求→web服务器接收后发送30X状态码响应及对应新的location给客户浏览器→客户浏览器发现是30X响应,则自动再发送一个新的http请求,请求url是新的location地址→服务器根据此请求寻找资源并发送给客户。//java代码示例response.sendRedirect(“xxx.jsp或者servlet”);2.转发过程:客户端浏览器发送http请求→web服务器接受此请求→

  • 三种最短路的总结

    三种最短路的总结

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号