电子字典(字典树)

news/2025/2/27 22:40:07/文章来源:https://www.cnblogs.com/bakul/p/18742130

P4407 [JSOI2009] 电子字典

题目描述

人们在英文字典中查找某个单词的时候可能不知道该单词的完整拼法,而只知道该单词的一个错误的近似拼法,这时人们可能陷入困境,为了查找一个单词而浪费大量的时间。带有模糊查询功能的电子字典能够从一定程度上解决这一问题:用户只要输入一个字符串,电子字典就返回与该单词编辑距离最小的几个单词供用户选择。

字符串 \(a\) 与字符串 \(b\) 的编辑距离是指:允许对 \(a\)\(b\) 串进行下列“编辑”操作,将 \(a\) 变为 \(b\)\(b\) 变为 \(a\),最少“编辑”次数即为距离。

  1. 删除串中某个位置的字母;
  2. 添加一个字母到串中某个位置;
  3. 替换串中某一位置的一个字母为另一个字母。

JSOI 团队正在开发一款电子字典,你需要帮助团队实现一个用于模糊查询功能的计数部件:对于一个待查询字符串,如果它是单词,则返回 \(-1\);如果它不是单词,则返回字典中有多少个单词与它的编辑距离为 \(1\)

输入格式

第一行包含两个正整数 \(N\)\(M\)

接下来的 \(N\) 行,每行一个字符串,第 \(i+1\) 行为单词 \(W_i\),单词长度在 \(1\)\(20\) 之间。

再接下来 \(M\) 行,每行一个字符串,第 \(i+N+1\) 表示一个待查字符串 \(Q_i\)。待查字符串长度在 \(1\)\(20\) 之间。\(W_i\)\(Q_i\) 均由小写字母构成,文件中不包含多余空格。

输出格式

输出应包括 \(M\) 行,第 \(i\) 行为一个整数 \(X_i\)

  • \(X_i = -1\) 表示 \(Q_i\) 为字典中的单词;

  • 否则 \(X_i\) 表示与 \(Q_i\) 编辑距离为 \(1\) 的单词的个数。

输入输出样例 #1

输入 #1

4 3
abcd
abcde
aabc
abced
abcd
abc
abcdd

输出 #1

-1
2
3

说明/提示

样例解释

  • abcd 在单词表中出现过;
  • abc 与单词 abcdaabc 的编辑距离都是 \(1\)
  • abcdd 与单词 abcdabcdeabced 的编辑距离都是 \(1\)

数据范围与约定

  • 所有单词互不相同,但是查询字符串可能有重复;
  • \(50\%\) 的数据范围,\(N,M\le 10^3\)
  • \(100\%\) 的数据范围,\(N,M\le 10^4\)

分析:

一部分单词存在字典树树中,查询一个字符串有几个单词可以通过增添,替换,删除一个字符的一个操作得到。

可以看作是对查询的字符串进行一个操作,查询字典树是否有这个单词。使用dfs进行搜索,首先需要考虑dfs的参数

  1. 现在操作的字符在字典树的哪个位置,因此需要变量p
  2. 处理到了字符串的哪个字符,需要标明字符串位置lenth
  3. 是否有已经编辑过一次字符串了 f
    所以使用void dfs(int p,int lenth,int f)

操作:

  1. 删除,直接相当于跳过该字符:dfs(p, lenth+1, 1)
  2. 替换,可以使用循环遍历26个字母,在son[p][i]存在的情况下搜索下一个字符dfs(son[p][i], lenth+1, 1)
  3. 增添,也是遍历26个字母,可以和替换一起,dfs(son[p][i], lenth, 1)
  4. 此外
#include <bits/stdc++.h>
//#define int long long
using namespace std;
const int N = 2e5 + 10;
int n,m,son[N][26],cnt[N],idx,lens,vis[N],ans,flag;     //vis记录单词是否已经到达过,一样的单词不能算两个,别忘了每次查询清空!
char s[22];                                        
inline void ins(char s[]) {                             //插入字典树int len = strlen(s),p = 0;for (int i = 0;i < len;++i) {int t = s[i] - 'a';while (!son[p][t]) son[p][t] = ++idx;p = son[p][t];}cnt[p]++;                                          //标记单词末尾}void dfs(int p,int lenth,int f) {if ( lenth == lens && cnt[p] && !f) {             //对于直接得到的单词cout << -1 << '\n';flag = 1;return;}if (lenth == lens && cnt[p] && !vis[p]) {         //对于修改后得到的单词vis[p] = 1;ans++;return;}if (!f) {                                           //在没有改动过的前提下if (lenth < lens) dfs(p,lenth+1,1);          //删除一个字符,注意删除条件for (int i = 0;i < 26;++i) {if (son[p][i]) dfs(son[p][i],lenth,1);     //增添操作if (i != s[lenth]-'a' && son[p][i]) dfs(son[p][i],lenth+1,1); //替换操作,注意i对应是s[lenth] - 'a',感觉i != s[lenth] - 'a'没用,确实可以ac,但是如果替换自己会发生什么?相当于没换,浪费了修改机会,但这种情况会在其他情况出现。还是留着保险}}if (lenth == lens) return;                          //前面循环已经有过增添了,所以不用担心在末尾增添加成为一个单词的情况if (son[p][s[lenth] - 'a']) dfs(son[p][s[lenth] - 'a'],lenth+1,f);  //正常查询}
signed main() {ios_base::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin >> n >> m;while (n--) {cin >> s;ins(s);}while (m--) {memset(vis,0,sizeof(vis));cin >> s;lens = strlen(s);ans = 0,flag = 0;dfs(0,0,0);if (!flag) cout << ans << '\n';}}

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

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

相关文章

Windows安装ollama运行deep seek R1模型+Page Assist浏览器插件本地使用

在Windows系统上安装Ollama并运行DeepSeek R1模型,同时结合Page Assist浏览器插件实现本地使用,可以按照以下步骤操作: 一、安装Ollama 下载Ollama: 访问Ollama官方网站,下载适用于Windows的版本。安装路径默认在c盘创建符号链接 原路径:C:\Users\18368\.ollama目标路径:…

上海海洋大学软件开发与创新课程设计作业

我给上学期其他同学的大作业添加了一些功能,已有的功能只有用户注册并填写账号密码,然后点击登录按钮成功登录 现在添加的新功能如下: 1,添加了一个真正可以选课的页面,添加了一些课程选项 2,可以存储用户选课的历史和方案 3,添加了一个管理员页面用于查看用户账号密码以…

Qwen2.5-0.5B siglip 预训练 / 微调实验

前言视频 | 仓库跟着教程做的,记录学习过程。 环境双卡 3090 24G CUDA 12.2 transformers 4.49概述 通过在 Qwen2.5-0.5B 和 siglip 之间训练一个中间层构造 VLM。作者提到首次微调时,只冻结了视觉模型的参数,导致阶梯状的 loss 曲线,即发生过拟合。应冻结文本和视觉模型的…

2025.2.27(Java的输出换行)

如图输出println,这个ln相当于输出完后自动换一次行。如图输出print,去掉ln不换行。

优化职工信息系统文件读写错误

该系统取自于大一时期的一个同班同学的期末大作业,该职工信息系统分别实现了职工信息的增删改查,以及计算职工的总工资和平均工资等功能。但是在编写了该系统之后,出现了一些问题,其中一个文件读写的问题我觉得需要进行改进,这个代码不能自己创建文本文档在指定的文件夹,…

PL端DDR4的MIG IP核配置及example design分析(个人记录)

第一种配置方法如下。按最高2666MHz配置,这边输入的参考时钟看个人板卡情况,我这边输入是200MHz。第二种配置方法如下。按2400MHz配置(需要换芯片型号),这边输入的参考时钟看个人板卡情况,我这边输入是200MHz。这边是输入时钟设置及输出时钟设置。我这边输入是差分时钟,…

Linux上部署deepseek-r1:7b模型

通过ollama在debian上安装部署deepseek-r1:7b模型。一、安装ollama框架 访问 ollama 官网,点击下载,选择 Linux,复制安装命令执行即可。二、下载并运行模型 选择 deepseek:7b 模型,复制安装命令执行即可。 (这里的模型参数大小,可根据自己的显存大小选择,可简单安装 0.5b…

LVI_SAM虚拟机安装复现(二)

0. 前言 前一篇文章里面,已经完成了 Ubuntu 18.04 和 ROS Melodic 的安装。 还没有安装好的读者,可以回去看这一篇文章。 前情概要: LVI_SAM虚拟机安装复现(一) 本文主要记录了GTSAM源码编译安装过程中经历的坑 警告:并非从零开始零基础教你安装 GTSAM 哦 GTSAM是一个开源…

逆向软件设计—网上购书结账系统

一、作业要求找一个已有的项目(同学、高年级同学、网络下载),阅读分析,找出软件尚存的缺陷, 改进其软件做二次开发,并将这个过程整理成一份博客。 二、原项目介绍 本次课程设计我逆向开发的软件是一个使用c++编写的网上购书结账系统,原作者是22软工2班的熊知宇学长,学号…

学生管理系统二次开发与优化实践

在软件开发中,对现有项目进行优化和二次开发是一种常见的任务。本次实验中,我选择了一个基于C++开发的学生管理系统作为优化对象。该系统实现了学生信息的增删改查功能,并支持学号排序和模糊查找等功能。通过分析原项目,我发现了几个可以改进的地方,并对系统进行了优化。以…

逆向软件工程

一、来源 本次实验项目来源于c++课程设计:线上图书购买系统 二、运行环境及运行结果 运行环境:vs 2022 Windows 11 运行结果:代码展示: `#include include include "Order.h" include "Book.h" void displayMenu() { std::cout << "1. Ad…

基于MPPT最大功率跟踪的离网光伏发电系统Simulink建模与仿真

1.课题概述 基于MPPT最大功率跟踪的离网光伏发电系统Simulink建模与仿真。2.系统仿真结果 (完整程序运行后无水印)3.核心程序与模型 版本:MATLAB2022a4.系统原理简介基于最大功率点跟踪(Maximum Power Point Tracking, MPPT)的离网光伏发电系统是利用太阳光直接转换为电能…