java单词查找树_Trie 单词查找树 java实现(来自算法第4版)

强烈建议看书上的实现步骤,这里只是一个个人记录。

单词查找树的性能:

查找命中所需的时间与被查找的键的长度成正比。比如单词有7个字符,查找或插入操作最多只需要检查8个节点。

查找未命中只需检查若干个字符。

所需空间:在RN~RNw之间,其中R为字母表大小,N为键的个数,w为平均单词长度。

import java.util.LinkedList;

import java.util.Queue;

/**

* @author yuan

* @date 2019/2/21

* @description 单词查找树,参考算法第4版

*/

public class TrieST {

/**

* 基数

*/

private static int R = 256;

/**

* 根节点

*/

private Node root;

private static class Node{

private Object val;

private Node[] next = new Node[R];

}

public Value get(String key) {

Node x = get(root, key, 0);

if (x == null) {

return null;

}

return (Value) x.val;

}

/**

* 返回以x作为根节点的子单词查找树中与key相关联的值

* @param x

* @param key

* @param d 当前的遍历深度

* @return

*/

private Node get(Node x, String key, int d) {

if (x == null) {

return null;

}

if (d == key.length()) {

return x;

}

char c = key.charAt(d);

return get(x.next[c], key, d + 1);

}

public void put(String key,Value val) {

root = put(root, key, val, 0);

}

/**

* 如果key存在以x为根节点的子单词查找树中则更新与它相关联的值

* @param x

* @param key

* @param val

* @param d

* @return

*/

private Node put(Node x, String key, Value val, int d) {

if (x == null) {

x = new Node();

}

if (d == key.length()) {

x.val = val;

return x;

}

// 找到第d个字符所对应的子单词查找树

char c = key.charAt(d);

x.next[c] = put(x.next[c], key, val, d + 1);

return x;

}

/**

* 查找所有的键

* @return

*/

public Iterable keys(){

return keysWithPrefix("");

}

/**

* 匹配以pre为前缀的键

* @param pre

* @return

*/

private Iterable keysWithPrefix(String pre) {

Queue q = new LinkedList<>();

collect(get(root, pre, 0), pre, q);

return q;

}

private void collect(Node x, String pre, Queue q) {

if (x == null) {

return;

}

if (x.val != null) {

q.offer(pre);

}

for (char c = 0; c < R; c++) {

collect(x.next[c], pre + c, q);

}

}

/**

* 匹配含通配符的键('.'能匹配所有字符)

* @param pat

* @return

*/

public Iterable keysThatMatch(String pat) {

Queue q = new LinkedList<>();

collect(root, "", pat, q);

return q;

}

private void collect(Node x, String pre, String pat, Queue q) {

int d = pre.length();

if (x == null) {

return;

}

if (d == pat.length() && x.val != null) {

q.offer(pre);

}

if (d == pat.length()) {

return;

}

char next = pat.charAt(d);

for (char c = 0; c < R; c++) {

if (next == '.' || next == c) {

collect(x.next[c], pre + c, pat, q);

}

}

}

/**

* 查找s中的最长的键

*

* @param s

* @return

*/

public String longestPrefixOf(String s) {

int length = search(root, s, 0, 0);

return s.substring(0, length);

}

private int search(Node x, String s, int d, int length) {

if (x == null) {

return length;

}

// 当前节点非空,更新length

if (x.val != null) {

length = d;

}

// 已经遍历到s的末尾,返回

if (d == s.length()) {

return length;

}

char c = s.charAt(d);

return search(x.next[c], s, d + 1, length);

}

/**

* 删除操作

* @param key

*/

public void delete(String key) {

root = delete(root, key, 0);

}

private Node delete(Node x, String key, int d) {

if (x == null) {

return null;

}

if (d == key.length()) {

x.val = null;

} else {

char c = key.charAt(d);

x.next[c] = delete(x.next[c], key, d + 1);

}

if (x.val != null) {

return x;

}

for (char c = 0; c < R; c++) {

if (x.next[c] != null) {

return x;

}

}

return null;

}

public static void main(String[] args) {

TrieST trieST = new TrieST<>();

trieST.put("abc", 3);

trieST.put("acc", 1);

trieST.put("bb", 1);

System.out.println(trieST.get("abc")); // 3

System.out.println();

Iterable iterable = trieST.keysThatMatch("a.c");

iterable.forEach(i -> System.out.println(i)); // abc acc

System.out.println();

trieST.delete("abc");

System.out.println(trieST.get("abc")); // null

}

}

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

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

相关文章

学python开发必须要会wsgi么_学python着几个要搞清楚WSGI和uWSGI区别

Python&colon; 解决pip安装源被墙的问题pip install -i http://mirrors.aliyun.com/pypi/simple --trusted-host mirrors.aliyun.c ...resin的简单介绍和使用1.resin是一款应用服务器(application server),它自身也包含一款支持Http1.1协议的WEB服务器(web server),它也可以…

java 连接 sftp失败_java – 文件上传到SFTP失败(Apache VFS)

我有一个SFTP问题(WindowsWinSSHD).我尝试用Apache Commons VFS在一个文件夹中写一个文件.在本地SFTP上我没有上传的问题,但在第二个SFTP上我总是得到以下错误.FTP看起来像这样&#xff1a;我需要上传到文件夹“alis”.奇怪的是它没有User / Group和770权限.但是,使用FileZilla…

基本农田卫星地图查询_如何基于西安80坐标查询定位

1. 概述水经注软件除了可以轻松下载无水印Google Earth卫星影像、有明确拍摄日期的历史影像、地方高清天地图、百度高德大字体打印地图&#xff0c;且可按1万/5千等国家标准图幅下载&#xff0c;下载含高度的全国矢量建筑、全国乡镇及街区行政区划、地名点、高速铁路网、公交路…

java getipaddress_教你java用getAddress方法取得IP地址

本篇教你java用getAddress方法取得IP地址&#xff1a;getAddress方法和getHostAddress类似&#xff0c;它们的唯一区别是getHostAddress方法返回的是字符串形式的IP地址&#xff0c;而getAddress方法返回的是byte数组形式的IP地址。getAddress方法的定义如下&#xff1a;public…

tcp的无延时发送_高并发架构的TCP知识介绍

这是关于高并发架构网络协议基础知识的第二篇&#xff0c;编程路上的基础心法&#xff01;做为一个有追求的程序员&#xff0c;不能只满足增删改查&#xff0c;我们要对系统全方面无死角掌控。掌握了这些基本的网络知识后&#xff0c;相信一方面日常排错中会事半功倍&#xff0…

java lambda sorted_Java8:Lambda表达式增强版Comparator和排序

1、概述在这篇教程里&#xff0c;我们将要去了解下即将到来的JDK 8(译注&#xff0c;现在JDK 8已经发布了)中的Lambda表达式——特别是怎样使用它来编写Comparator和对集合(Collection)进行排序。首先&#xff0c;让我们先定义一个简单的实体类&#xff1a;public class Human …

如何对一个变量数据进行正则判定_生存分析数据中的BuckleyJamesMultipleRegression Model...

一、模型简介目前&#xff0c;生存分析领域&#xff0c;最常用的是Cox比例风险回归模型&#xff0c;该模型具有良好的特性&#xff0c;不仅可以分析各种自变量对生存时间的影响&#xff0c;而且对基准风险分布不作任何要求(半参数模型)。Cox模型使用时要满足一定的条件&#xf…

格兰杰因果关系检验r语言_R语言系列第四期:R语言单样本双样本差异性检验

之前详细介绍了利用R语言进行统计描述&#xff0c;详情点击&#xff1a;R语言系列第三期&#xff1a;①R语言单组汇总及图形展示、R语言系列第三期&#xff1a;②R语言多组汇总及图形展示、R语言系列第三期&#xff1a;③R语言表格及其图形展示从这个部分我们就开始为大家介绍统…

python数据预测代码_手把手教你用Python玩转时序数据,从采样、预测到聚类丨代码...

原标题&#xff1a;手把手教你用Python玩转时序数据&#xff0c;从采样、预测到聚类丨代码原作 Arnaud Zinflou郭一璞 编译时序数据&#xff0c;也就是时间序列的数据。像股票价格、每日天气、体重变化这一类&#xff0c;都是时序数据&#xff0c;这类数据相当常见&#xff0c;…

java 配置jmstemplate_SpringBoot集成JmsTemplate(队列模式和主题模式)及xml和JavaConfig配置详解...

1.导入jar包&#xff1a;org.springframework.bootspring-boot-starter-activemqorg.apache.activemqactivemq-pool2.填写配置文件(application.properties)#设置JMS(AMQ)spring.activemq.broker-urltcp://localhost:61616spring.activemq.useradminspring.activemq.passwordad…

切面是异步还是同步操作‘_分布式中采用Logback的MDC机制与AOP切面结合串联日志...

导读&#xff1a;在实际开发中&#xff0c;打印日志是十分重要的。在生产环境中&#xff0c;如果日志打得好可以快速地排查问题&#xff0c;而在分布式的场景下&#xff0c;一个请求会跨越多个节点&#xff0c;既一个业务可能需要多个节点协调配合处理。那么日志将会分散&#…

java 图类_Java集合类,一张图说清楚!

作者&#xff1a;skywang12345https://www.cnblogs.com/skywa...2019-03-23 10:32:24Java集合是java提供的工具包&#xff0c;包含了常用的数据结构&#xff1a;集合、链表、队列、栈、数组、映射等。Java集合工具包位置是java.util.*&#xff0c;Java集合主要可以划分为4个部分…

python 取整_马克的Python学习笔记#数字,日期和时间

对数值进行调整在Python中对整数和浮点数进行数字计算是很容易的。但是&#xff0c;如果你需要对分数&#xff0c;数组或者日期和时间进行计算&#xff0c;这就会稍微复杂点。对于简单的取整操作&#xff0c;我们可以使用内建的round(value, ndigits)函数就可&#xff0c;举个例…

java 数据类型分为_JAVA中分为基本数据类型及引用数据类型

byte&#xff1a;Java中最小的数据类型&#xff0c;在内存中占8位(bit)&#xff0c;即1个字节&#xff0c;取值范围-128~127&#xff0c;默认值0short&#xff1a;短整型&#xff0c;在内存中占16位&#xff0c;即2个字节&#xff0c;取值范围-32768~32717&#xff0c;默认值0i…

各路由协议的协议号_厂房转让协议

厂房转让协议转让方(甲方)&#xff1a;________________受让方(乙方)&#xff1a;________________甲乙双方本着平等互利的原则&#xff0c;经协商一致就甲方将其权属的工业用地、厂房等转让与乙方及有关事项达成如下协议:一、工业用地及厂房产权基本情况本协议转让的工业用地位…

java容器怎么封装的_docker怎么把容器打包成镜像

1.首先引用 maven docker插件&#xff0c;打开 java应用jar包&#xff0c;点击package按钮&#xff1b;2.新建一个docker文件夹&#xff0c;将导出的jar包放入到此文件夹中&#xff1b;3.新建一个Dockerfile文件&#xff0c;输入以下打包命令FROM frolvlad/alpine-oraclejdk8:s…

python 异常回溯_关于python:在循环中捕获异常回溯,然后在脚本末尾引发错误...

我正在尝试捕获所有异常错误&#xff0c;然后在脚本结尾处使其引发/显示所有回溯...我有一个主脚本&#xff0c;例如调用我的下标&#xff1a;errors open(MISC/ERROR(S).txt, a)try:execfile("SUBSCRIPTS/Test1.py", {})except Exception:## Spread over two calls…

java web开发常见问题_JavaWeb学习笔记(五)--Web开发其他常见问题

一、把web应用打成war包使用JDK自带jar命令&#xff0c;进入到web应用里面&#xff0c;执行命令&#xff1a;jar -cvf 包名.war . # .表示当前目录所有的文件 直接用jar可查看帮助执行完成后生成一个demo.war文件&#xff0c;把这个文件拷贝到Tomcat的webapps下&#xff0c;Tom…

mysql having in_MySQL中无GROUPBY直接HAVING的问题

本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/having_without_groupby_in_mysql.html 今天有同学给我反应&#xff0c;有一张表&#xff0c;id是主键&#xff0c;这样的写法可…

python求线段长度_python微元法计算函数曲线长度的方法

计算曲线长度&#xff0c;根据线积分公式&#xff1a;&#xff0c;令积分函数f(x,y,z) 为1&#xff0c;即计算曲线的长度&#xff0c;将其微元化&#xff1a;其中根据此时便可在python编程实现&#xff0c;给出4个例子&#xff0c;代码中已有详细注释&#xff0c;不再赘述计算曲…