使用Trie数据结构实现搜索自动完成功能

本文旨在讨论使用 Java 的搜索自动完成的低级实现,将Trie在用例中使用数据结构。

这是一个示例TrieNode类:

class TrieNode{
Map<Character,TrieNode> children;
boolean isEndOfWord;

    TrieNode(){
children = new HashMap<>();
isEndOfWord = false;
}
}

请注意,我们在这里使用 Map 来存储 Trie 中特定层级的所有字符。
如果问题是按字母顺序返回结果,那么我们别无选择,只能使用 TreeMap,能确保顺序,但会在插入和搜索时耗费时间,因为 TreeMap 查找/插入将耗费 log(n) 时间。

在本文中,我们假设可以按任意顺序返回结果,以使事情变得简单。

另外,假设我们有来自后台的缓存响应。我们可以将其作为自动完成任务的单词来源。让这个输入是单词,假设我们正在搜索一个单词 searchWord 。因此,方法定义可归结为以下内容:

public List suggestedWords(String[] words,
String searchWord) {
for (String word: words) {
insert(word); // insert to Trie }
return search(searchWord); // search in Trie and return results
}

方法 insert(String word) 可以在 Trie 中插入单词。
以下是该方法的示例实现。
请注意,我们需要将最后一个 TrieNode 的 isEndOfWord 标志设置为 true,表示单词的最后一个字符。

private void insert(String word) {
int len = word.length();
TrieNode current = this.root; // member variable pointing to the root of TrieNode for (int i = 0; i < len; i++) {
TrieNode node = current.children.get(word.charAt(i));
if (node == null) {
node = new TrieNode();
current.children.put(word.charAt(i), node);
}
current = node;
}
current.isEndOfWord = true;
}

Trie 可以预先填充,也可以在应用服务器中设置。

因此,实时查询只需直接调用 search(searchWord)。在插入一堆单词后,它看起来就像下面这样(例如:apple, ape, god, good):

现在到了主要部分,即搜索自动完成。
首先,我们需要实现前缀搜索。
我们应该能够在 Trie 中搜索前缀。如果找到匹配,我们就需要搜索该特定 TrieNode 中的完整单词。实时应用将返回 k 个结果,而不是所有单词。
为了实现实时性能,返回 k 个单词是合理的。以下是前缀搜索的实现:

private TrieNode startsWith(String prefix) {
int len = prefix.length();
TrieNode current = this.root;

  for (int i = 0; i < len; i++) {
TrieNode node = current.children.get(prefix.charAt(i));
if (node == null) {
return null;
}
current = node;
}
return current;
}

如果在 Trie 中没有找到前缀,我们将返回 null,否则我们将返回 TrieNode 作为主要搜索的起点。在最坏的情况下,前缀搜索只需要 O(n) 时间。下面,让我用迄今为止定义的所有方法重写搜索函数:

private List search(String searchWord) {
List result = new ArrayList <> ();
TrieNode current = this.root;
int len = searchWord.length();

  current = startsWith(searchWord);
if (current != null) {
List list = new ArrayList <> ();
StringBuilder sb = new StringBuilder(searchWord);
// backtrack(list, current, sb, k); yet to implement. result.addAll(list);
}
return result;
}

请注意,searchWord 可能是一个完整的词,也可能不是。但这并不重要,我们会返回 searchWord 的所有完整单词。我已经对上述代码进行了注释,这些代码还有待讨论/实现。我们可以使用回溯法从前缀 TrieNode 开始遍历所有后续 TrieNode,直到找到一个完整的单词。请参考下面的实现:

private void backtrack(List list,
TrieNode current,
StringBuilder sb,
int k) {
if (list.size() == k) {
return;
}
if (current.isEndOfWord) {
list.add(sb.toString());
}
for (Map.Entry<Character,TrieNode> entry: current.children.entrySet()) {
sb.append(entry.getKey());
backtrack(list, entry.getValue(), sb);
sb.setLength(sb.length() - 1);
}
}

当最多收集到 k 个单词时,我们就停止回溯 Trie。最重要的是,我们会借助 isEndOfWord 标志来收集单词。StringBuilder 的使用在此不言自明。一旦完成回溯,结果将包含所有完整的单词。现在,如果我们需要返回短语列表而不是单词列表,也可以采用同样的解决方案。这里的单词是短语的同义词,所以并不重要。

您可以在实际的编码面试中快速完成编码,改进的空间是无限的!编码快乐

https://www.jdon.com/71720.html

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

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

相关文章

Unity 利用UGUI之Scrollbar制作进度条

在Unity中除了用Slider、Image做进度条&#xff0c;其实用Scrollbar也可以做进度条。 首先&#xff0c;在场景中新建一个Scrollbar组件和一个Text组件&#xff1a; 其次&#xff0c;创建模拟进度的一个脚本&#xff0c;Scrollbar_Progressbar.cs: using System.Collections; …

Linux:linux计算机和windows计算机 之间 共享资源

在前面章节已经介绍过&#xff0c;NFS用于Linux系统之间的文件共享&#xff0c;windows 并不知道 NFS &#xff0c;而是使用 CIFS (Common Internet File System) 的协议机制 来 “共享” 文件。在1991年&#xff0c;Andrew Tridgell 通过逆向工程 实现了 CIFS 协议&#xff0c…

中兴通讯5G-A场景突破成果显著,获得行业高度认可

近年来&#xff0c;中兴通讯持续发力5G-A场景&#xff0c;积极进行相关技术研发&#xff0c;为6G时代的到来铺路。2023年12月28日&#xff0c;在2024&#xff08;第二十届&#xff09;ICT行业趋势年会“ICT龙虎榜揭榜盛典”当中&#xff0c;中兴通讯获得“2023年度5G-A场景开拓…

学习笔记——C++二维数组

二维数组定义的四种方式&#xff1a; 1&#xff0c;数据类型 数组名[ 行数 ][ 列数 ]&#xff1b; 2&#xff0c;数据类型 数组名[ 行数 ][ 列数 ]{{数据1&#xff0c;数据2}&#xff0c;{数据3&#xff0c;数据4}}&#xff1b; 3&#xff0c;数据类型 数组名[ 行数…

Vue3导出el-table为execl文件

在开发时遇到了这样的需求&#xff0c;整理之后向大家分享一下&#xff0c;欢迎积极讨论与指正哦 因为在实现表格时使用了分页插件&#xff0c;在导出时只能导出本页的内容&#xff0c;最后选择了这样的方法&#xff1a; 正常显示的表格使用分页后的数据 在这里设置了id 而用…

了解 Node.js 的运行机制:从事件循环到模块系统(上)

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Java索引优先队列设计思路与实现

Java 学习面试指南&#xff1a;https://javaxiaobear.cn 1、实现思路 存储数据时&#xff0c;给每一个数据元素关联一个整数&#xff0c;例如insert(int k,T t),我们可以看做k是t关联的整数&#xff0c;那么我们的实现需要通过k这个值&#xff0c;快速获取到队列中t这个元素&a…

使用使用maven后jstl标签库无法使用

创建maven项目后配置了jstl标签库的依赖&#xff0c;但是一直不行&#xff0c;jsp页面还是原样给我输出&#xff0c;然后去网上找了许多办法&#xff0c;类似于配置文件之类的&#xff0c;结果发现对我并没有什么用&#xff0c;还是原样输出 然后就各种查找&#xff0c;发现了一…

大数据本地环境搭建-Linux基础环境搭建

1.安装VMware 下载 VMware Workstation Pro | CN 2.配置虚拟网卡 3.Windows网络配置 4.安装centos7.9 Download (centos.org) 4.1 新建虚拟机 如果开机的时候电脑蓝屏使用WindowsR输入optionalfeatures 打开启用或关闭Windows功能->勾选打开以下两项 重启 继续安装ce…

C++力扣题目-- 二叉树层序遍历

102.二叉树的层序遍历(opens new window)107.二叉树的层次遍历II(opens new window)199.二叉树的右视图(opens new window)637.二叉树的层平均值(opens new window)429.N叉树的层序遍历(opens new window)515.在每个树行中找最大值(opens new window)116.填充每个节点的下一个右…

WPS或word中英文字母自动调整大小写,取消自动首字母大写,全部英文单词首字母大小写变换方法

提示&#xff1a;写英文论文时&#xff0c;如何实现英文字母大小写的自动切换&#xff0c;不用再傻傻的一个字母一个字母的编辑了&#xff0c;一篇文章搞定WPS与Word中字母大小写切换 文章目录 一、WPS英文单词大小写自动修改与首字母大写调整英文字母全部由大写变成小写 或 小…

怎样的摆渡系统,能实现安全可管控的跨网数据传输?

大数据时代&#xff0c;数据在流通与传输的过程中&#xff0c;更需要注意到数据的安全防护&#xff0c;护航数据价值。“让数据主宰一切的隐忧”&#xff0c;数字战争的时代&#xff0c;各国早已认识到网络安全愈发重要&#xff0c;数据也成为各国发展的重要武器。 出于安全性和…

爬虫瑞数5.5案例:某证券

声明&#xff1a; 该文章为学习使用&#xff0c;严禁用于商业用途和非法用途&#xff0c;违者后果自负&#xff0c;由此产生的一切后果均与作者无关 一、瑞数简介 瑞数动态安全 Botgate&#xff08;机器人防火墙&#xff09;以“动态安全”技术为核心&#xff0c;通过动态封装…

SwiftUI之深入解析Alignment Guides的超实用实战教程

一、Alignment Guide 简介 Alignment guides 是一个强大的布局工具&#xff0c;但通常未被充分利用。在很多情况下&#xff0c;它们可以帮助我们避免更复杂的选项&#xff0c;比如锚点偏好。如下所示&#xff0c;对对齐的更改也可以自动&#xff08;并且容易地&#xff09;动画…

Spring Cloud 介绍

文章目录 微服务技术栈Spring Cloud 介绍京东、阿里的微服务架构SpringBoot 和 SpringCloud 版本选择Springboot版本选择Springcloud版本选择Springcloud和Springboot之间的依赖关系如何看Spring Cloud 组件的升级替换 微服务技术栈 [toc] Spring Cloud 介绍 Spring Cloud是…

ULINK2仿真器安装使用之工程设置

一、 ULINK2仿真器 ULINK2是ARM公司最新推出的配套RealView MDK使用的仿真器&#xff0c;是ULink仿真器的升级版本。ULINK2不仅具有ULINK仿真器的所有功能&#xff0c;还增加了串行调试&#xff08;SWD&#xff09;支持&#xff0c;返回时钟支持和实时代理等功能。开发工程师通…

基于python热门旅游景点推荐系统+爬虫技术

大数据分析&#xff0c;数据可视化等皆可用。 源码分享。

vue-vben-admin 与.net core 结合实例 【自学与教学 小白教程】---第3节

ue-vben-admin 与.net core 结合实例 这里计划使用.net core 作为后端 。目标&#xff1a;打造好看 易用 开箱即用 的netcore一体化框架。Vue Vben Admin For NetCore 取命 hcrain-vvadmin 我不是前端人员 但有时开发还是要写一些界面。 之前使用layui是时候 狠心升级下了。 …

kubesphere和k8s的使用分享

文章目录 什么是kubernetesKubernetes的部分核心概念互式可视化管理平台与kubernetes的关系市面是常见的kubernetes管理平台 什么是kubesphereKubesphere默认安装的组件Kubesphere涉及的服务组件kubesphere的安装Kubesphere相关的内容 什么是kubernetes 就在这场因“容器”而起…

性能优化--实战利用arthas排查java服务cpu占用过高的问题

使用jps -l查看目前的java应用进程 启动arthas&#xff0c;选择需要监控的进程 dashboar查看该应用整体情况 使用thread命令&#xff0c;查看占用cpu过高的几个线程ID 然后使用thread 线程ID查看具体线程在执行哪些内容&#xff0c;可以看到对应的类和方法 正在上传… 重…