字典树(Trie树)的原理与实现

一、概述

1.1 基本概念

字典树,又称为单词查找树,Tire数,是一种树形结构,它是一种哈希树的变种。

在这里插入图片描述

1.2 基本性质

  • 根节点不包含字符,除根节点外的每一个子节点都包含一个字符
  • 从根节点到某一节点。路径上经过的字符连接起来,就是该节点对应的字符串
  • 每个节点的所有子节点包含的字符都不相同

1.3 应用场景

典型应用是用于统计,排序和保存大量的字符串(不仅限于字符串),经常被搜索引擎系统用于文本词频统计。

1.4 优点

利用字符串的公共前缀来减少查询时间,最大限度的减少无谓的字符串比较,查询效率比哈希树高。

二、trie树的构建与操作实现

2.1 字典树节点定义

//定义字典表节点(简化设计,仅兼容26个小写英文字符)
class TrieNode {private int num; //有多少单词经过当前节点,即由根节点到该节点组成的字符串模式出现的次数private TrieNode[] son;//子节点数组private boolean wordEnd;//是否是叶子结点private char val;//当前节点的值TrieNode() {num =1;son = new TrieNode[engNum];wordEnd = false;}
}

2.2 字典树构造函数

public Trie() {root = new TrieNode();}

2.3 建立字典树

//建立字典树
public void insert(String str) {if(StringUtils.isEmpty(str)) {return;}TrieNode curNode = root;char[] arr = str.toCharArray();for(char c:arr) {int index = c-'a';TrieNode node = curNode.son[index];if(node == null) {//当前节点为空则创建curNode.son[index] = new TrieNode();curNode.son[index].val = c;}else {//不为空则加一node.num = node.num +1;}curNode = curNode.son[index];}curNode.wordEnd = true;
}

2.4 在字典树中查找是否完全匹配一个指定的字符串

//在字典中查找一个完全匹配的单词
public boolean has(String str) {if(StringUtils.isEmpty(str)) {return false;}TrieNode node = root;//找到指定前缀在字典树的位置char[] arr = str.toCharArray();for(int i=0;i<arr.length;i++) {int index = arr[i] -'a';if(node.son[index] == null) {return false;}node = node.son[index];}//到这里,如果最后的字符是叶子结点,则完全匹配;否则为部分匹配;return node.wordEnd;
}

2.5 前序遍历字典树

//前序遍历字典树
public void preTraverse(TrieNode root) {if(root != null) {System.out.println(root.val);for(TrieNode son: root.son) {preTraverse(son);}}
}

2.6 计算指定前缀的单词的数量

//计算指定前缀的单词的数量
public int countPrefix(String prefix) {if(StringUtils.isEmpty(prefix)) {return 0;}TrieNode node = root;char[] arr = prefix.toCharArray();for(int i=0;i<arr.length;i++) {int index = arr[i] -'a';if(node.son[index] == null) {return 0;}node = node.son[index];}return node.num;
}

2.7 完整代码


public class Trie {public static int asciiNum = 128;public static int engNum = 26;private TrieNode root;public Trie() {root = new TrieNode();}//定义字典表节点(简化设计,仅兼容26个小写英文字符)class TrieNode {private int num; //有多少单词经过当前节点,即由根节点到该节点组成的字符串模式出现的次数private TrieNode[] son;//子节点数组private boolean wordEnd;//是否是叶子结点private char val;//当前节点的值TrieNode() {num =1;son = new TrieNode[engNum];wordEnd = false;}}//建立字典树public void insert(String str) {if(StringUtils.isEmpty(str)) {return;}TrieNode curNode = root;char[] arr = str.toCharArray();for(char c:arr) {int index = c-'a';TrieNode node = curNode.son[index];if(node == null) {//当前节点为空则创建curNode.son[index] = new TrieNode();curNode.son[index].val = c;}else {//不为空则加一node.num = node.num +1;}curNode = curNode.son[index];}curNode.wordEnd = true;}//计算指定前缀的单词的数量public int countPrefix(String prefix) {if(StringUtils.isEmpty(prefix)) {return 0;}TrieNode node = root;char[] arr = prefix.toCharArray();for(int i=0;i<arr.length;i++) {int index = arr[i] -'a';if(node.son[index] == null) {return 0;}node = node.son[index];}return node.num;}//打印指定前缀的单词public void hasPrefix(String prefix) {if(StringUtils.isEmpty(prefix)) {return;}TrieNode node = root;//找到指定前缀在字典树的位置char[] arr = prefix.toCharArray();for(int i=0;i<arr.length;i++) {int index = arr[i] -'a';if(node.son[index] == null) {return;}node = node.son[index];}//前序遍历字典树preTraverse(node, prefix);}private void preTraverse(TrieNode node, String prefix) {if(node.wordEnd) {System.out.println(prefix);}for(TrieNode son : node.son) {if(son != null) {preTraverse(son, prefix + son.val);}}}//在字典中查找一个完全匹配的单词public boolean has(String str) {if(StringUtils.isEmpty(str)) {return false;}TrieNode node = root;//找到指定前缀在字典树的位置char[] arr = str.toCharArray();for(int i=0;i<arr.length;i++) {int index = arr[i] -'a';if(node.son[index] == null) {return false;}node = node.son[index];}//到这里,如果最后的字符是叶子结点,则完全匹配;否则为部分匹配;return node.wordEnd;}//前序遍历字典树public void preTraverse(TrieNode root) {if(root != null) {System.out.println(root.val);for(TrieNode son: root.son) {preTraverse(son);}}}public static void main(String[] args) {Trie trie = new Trie();String [] arr = new String[]{"string","str","study","strong","tech", "teach","teacher"};trie.insert("");for(String str: arr) { trie.insert(str);}
//		trie.preTraverse(trie.root);String prefix ="tea";System.out.println(trie.countPrefix(prefix));trie.hasPrefix(prefix);String word = "teach";System.out.println(trie.has(word));}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313542.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介

点击蓝字“dotNET匠人”关注我哟加个“星标★”&#xff0c;每日 7:15&#xff0c;好文必达&#xff01;什么要刷LeetCode大家都知道&#xff0c;很多对算法要求高一点的软件公司&#xff0c;比如美国的FLAGM (Facebook、LinkedIn、Amazon/Apple、Google、Microsoft)&#xff0…

.NET Core迁移前的准备工作

前段时间迁移.NET Core做了大量的试水和评估&#xff0c;今天整理一下分享给大家。大致有以下几个部分&#xff1a;1. .NET Core的由来2. 为什么要迁移.NET Core3. .NET Core3.X主要特性4. .NET Standard和.NET Core5. .NET Core Roadmap&版本选择接下来&#xff0c;我们详…

二叉排序树或二叉搜索树

一、二叉树基础 1.1 二叉排序树定义 二叉排序树&#xff08;Binary Sort Tree&#xff09;又称二叉查找(搜索)树&#xff08;Binary Search Tree&#xff09;。它是一颗空树&#xff0c;或者具有下列性质&#xff1a; 若它的左子树不为空&#xff0c;则左子树上所有结点的值…

沈向洋对于工程技术人员的十点经验分享

沈向洋目前是微软的执行副总裁&#xff0c;人工智能与研究部门的最高负责人。他是计算机视觉和图形学研究的世界级专家&#xff0c;是美国电气电子工程协会院士&#xff08;IEEE Fellow&#xff09;及是国际计算机协会院士&#xff08;ACM Fellow&#xff09;&#xff0c;曾任国…

.Net Core中间件和过滤器实现错误日志记录

1.中间件的概念ASP.NET Core的处理流程是一个管道&#xff0c;中间件是组装到应用程序管道中用来处理请求和响应的组件。每个中间件可以&#xff1a;选择是否将请求传递给管道中的下一个组件。可以在调用管道中的下一个组件之前和之后执行业务逻辑。中间件是一个请求委托&#…

最大堆、最小堆Java实现,解决TOP K问题

一、基础知识 1.1 什么是最大&#xff08;小&#xff09;堆 最大堆&#xff0c;最小堆类似&#xff0c;以下以最小堆为例进行讲解。 最小堆是满足以下条件的数据结构&#xff1a; 它是一棵完全二叉树所有父节点的值小于或等于两个子节点的值 1.2 什么是完全二叉树 除了最后…

使用Helm将ASP.NET Core应用程序部署到Kubernetes容器集群

在《容器化单页面应用中RESTful API的访问》以及《容器化单页面应用中Nginx反向代理与Kubernetes部署》两篇文章中&#xff0c;我介绍了一套容器化ASP.NET Core应用程序的方案&#xff0c;并对于Nginx反向代理的使用进行了介绍。在《使用Rancher在Microsoft Azure上搭建Kuberne…

微软如何利用机器学习改进Win 10更新体验

微软在 2018 年 4 月 Windows 更新时第一次大规模使用机器学习&#xff08;ML&#xff09;&#xff0c;ML 通过监测 PC 运行状况的六个核心领域&#xff08;例如总体可靠性&#xff09;&#xff0c;以确定功能更新过程是否顺利进行。而在 2019 年 5 月发布的更新推送中&#xf…

使用.NET Core创建Windows服务(一) - 使用官方推荐方式

原文&#xff1a;Creating Windows Services In .NET Core – Part 1 – The “Microsoft” Way创建Windows服务来运行批处理任务或者运行后台任务&#xff0c;是一种非常常见的模式&#xff0c;但是由于云服务&#xff08;Amazon Lambda, Azure WebJobs以及Azure Functions&am…

关于.NET HttpClient方式获取微信小程序码(二维码

随着微信小程序的火热应用&#xff0c;市面上有关小程序开发的需求也多了起来。近来分析了一项生成有关生成微信小程序码的需求——要求扫码跳转到小程序指定页面&#xff08;带参数&#xff09;&#xff1b;看了下小程序官方文档&#xff0c;以及网上的例子&#xff0c;未看到…

从零开始使用Skywalking分布式链路追踪系统

当我们用很多服务时&#xff0c;各个服务间的调用关系是怎么样的&#xff1f;各个服务单调用的顺序\时间性能怎么样?服务出错了&#xff0c;到底是哪个服务引起的&#xff1f;这些问题我们用什么方案解决呢&#xff0c;以前的方式是各个系统自己单独做日志&#xff0c;出了问题…

快速排序 (Quick Sort)(Java实现)

快速排序&#xff08;Quicksort&#xff09;是对冒泡排序的一种改进&#xff0c;借用了分治的思想&#xff0c;由C. A. R. Hoare在1962年提出。 1、基本思想 快速排序的基本思想&#xff1a;挖坑填数分治法。 首先选一个轴值(pivot&#xff0c;也有叫基准的)&#xff0c;通过…

使用.net core3.0 正式版创建Winform程序

前阵子一直期待.net core3.0正式版本的出来&#xff0c;以为这个版本出来&#xff0c;Winform程序又迎来一次新生了&#xff0c;不过9.23日出来的马上下载更新VS&#xff0c;创建新的.net core Winform项目&#xff0c;发现并没有Winform窗体设计器。而微软目前则是通过插件的方…

深入理解 ValueTask

.NET Framework 4 里面的命名空间为 System.Threading.Tasks的 Task 类。这个类以及它派生的 Task<TResult> 早已成为编程的主要部分&#xff0c;在 C#5 中的异步编程模式当作介绍了 async/await。在这篇文章里&#xff0c;我会覆盖新的类 ValueTask / ValueTask<TRes…

NET Core 3.0 AutoFac替换内置DI的新姿势

.NET Core 3.0 和 以往版本不同&#xff0c;替换AutoFac服务的方式有了一定的变化&#xff0c;在尝试着升级项目的时候出现了一些问题。原来在NET Core 2.1时候&#xff0c;AutoFac返回一个 IServiceProvider 参数注入到ConfigureServices .NET Core 服务中&#xff0c;基本大痣…

asp.net core 使用Mysql和Dapper

序曲&#xff1a;学习编程最好的方式就是敲代码&#xff0c;没有比这个更好的方法&#xff0c;哪怕你看了上百G的视频&#xff0c;都不如你自己敲几行代码更为有效。还有要记得敲完代码然后写一篇随笔来记录一下你所学所想。大家都知道&#xff0c;.netcore是微软一个具有历史意…

CSFR(跨站请求伪造)攻击与防御

一、CSRF是什么&#xff1f; CSRF&#xff08;Cross-site request forgery&#xff09;&#xff0c;中文名称&#xff1a;跨站请求伪造&#xff0c;也被称为&#xff1a;one click attack/session riding&#xff0c;缩写为&#xff1a;CSRF/XSRF。 二、CSRF可以做什么&#…

Vue 3源码公布

10 月 5 日凌晨&#xff0c;Vue.js 框架的作者兼核心开发者尤雨溪公布了尚处于 Pre-Alpha 状态的 Vue 3 源码。说学不动的童鞋抓紧剩余的假期时间撸一遍源码吧 : D作者表示&#xff0c;Vue 3 主要的架构改进、优化和新功能均已完成&#xff0c;剩下的主要任务是完成一些 Vue 2 …

在副业刚需的时代,如何掌握副业的正确姿势?

前言近期&#xff0c;伴随着“副业刚需”这个词语的流行&#xff0c;关于“职场人要不要发展副业”的话题再一次被炒得沸沸扬扬。有人认为副业是刚需&#xff0c;是抵御中年危机的锦囊妙计&#xff0c;甚至是中年人该有的自觉&#xff0c;没有副业的人不足以谈人生&#xff0c;…

使用.NET Core创建Windows服务(二) - 使用Topshelf方式

原文&#xff1a;Creating Windows Services In .NET Core – Part 2 – The “Topshelf” Way作者&#xff1a;Dotnet Core Tutorials译者&#xff1a;Lamond Lu译文&#xff1a;使用.NET Core创建Windows服务&#xff08;二&#xff09; - 使用Topshelf方式使用.NET Core创建…