【C++数据结构 | 哈希表速通】哈希表完成英汉词典增删改查 | 哈希表实现类型unordered_map详解

哈希表

by.Qin3Yu

ps.本文的哈希表特指unordered_map实现类型

文中所有代码默认已使用std命名空间且已导入部分头文件:

#include <iostream>
#include <unordered_map>
using namespace std;

概念速览

什么是键值对?

  • 所谓 键值对,顾名思义就是 组成的 对子,通过键,我们可以快速的找到值。比如在学校中,学号学生 就是一个键值对;在词典中,dog 就是一个键值对。键和值可以是不同的数据类型,如 商品名称(string型)商品价格(float型) 也可以是一个键值对。

在这里插入图片描述

  • 特别注意:值不一定是唯一的,但是键一定是唯一的。 打个比方:学号一定是唯一的,但是学生名字可能有重名的。

在这里插入图片描述

什么是哈希表?

  • 哈希表简单来说就是储存键值对的容器
  • 哈希表的定义是一种通过哈希函数将数据映射到数组中的数据结构。它的目的是实现快速的插入、删除和查找操作。哈希表的基本思想是将通过哈希函数转换为一个确定的索引,然后将对应的存储在该索引位置上。

在这里插入图片描述

  • 当需要查找或删除一个键对应的值时,再次利用哈希函数计算得到索引,从相应位置上获取或删除对应的值,以达到快速查找的目的。

优势
1.高效性: 哈希表能够在平均情况下实现O(1)时间复杂度的插入和查找操作。
2.灵活性: 哈希表可以存储不同类型的数据。
3.调节性: 哈希表支持动态扩展,即使在插入大量元素时,也能够自动调整内部的存储空间大小。

缺点
1.内存消耗: 哈希表在存储数据时需要额外的内存来存储散列桶、指针等信息。
2.冲突消耗: 由于散列函数可能将不同的键映射到相同的散列桶位置,一个不好的散列函数可能导致冲突过多,从而降低效率。


哈希表操作

声明一个哈希表( unordered_map )

  • 我们可以直接在函数中使用 unordered_map<T1, T2> name 声明一个哈希表,其中T1表示键(key)的类型,T2表示值(value)的类型,name表示哈希表的名字。在本文中,我们使用名为hs的字符串键值对哈希表来举例:
unordered_map<string, string> hs;  //声明一个名为hs的哈希表,他的键和值都是字符串类型

插入键值对( insert )

  • 现在我们已经有了一个空的字符串哈希表,,我们可以通过 hs.insert({ key,value }) 方法来将键值对插入哈希表。在本文中,我们以制作词典为例,我们使用的键值对是单词 - 翻译,因此,我们可以向我们的词典哈希表中插入一些单词和翻译的键值对:
//注意,“键值对”顾名思义,前者为键,后者为值
hs.insert({ "蝾螈", "newt" });
hs.insert({ "章鱼", "octopus"});
hs.insert({ "水豚", "capybara"});
hs.insert({ "牛蛙", "bullfrog" });
hs.insert({ "臭鼬", "skunk" });
  • 另外,我们也可以通过控制台输入来添加键值对,只需向 hs.insert({ key,value }) 传入相应参数即可:
cout << "请输入中文:";
string chinese; cin >> chinese;  //输入中文为键
cout << "请输入英文:";
string english; cin >> english;  //输入翻译为值
hs.insert({ chinese, english });  //插入 { 中文,翻译 } 键值对
  • ps.请注意,哈希表中的元素是没有先后顺序的。

删除键值对( erase )

  • 我们已经向哈希表中插入了一些数据,但假如其中的一些键值对输入错误,或者我们不再需要某些键值对,我们则需要做出删除键值对的操作。我们可以通过 hs.erase(key) 方法删除键值对。
  • 注意:此方法只可通过键来删除键值对。若想通过值删除键值对,可以采用后文说到的遍历方法,先找出键,然后再通过键删除键值对。
hs.insert({ "狗", "dag" });  //单词dog拼写错误,需要删除键值对
hs.erase("狗");  //删除 { 狗 , dog } 键值对
hs.insert({ "臭鼬", "skunk" });  //我不喜欢臭鼬,所以删除 { 臭鼬 , skunk } 键值对

查询值

  • 要查询哈希表中的值,我们只需要使用类似索引的方法 hs[key] 即可,此部分很简单,我们直接举例说明:
cout << hs["水豚"];  //哈希表中对应的键值对为 { 水豚 , kapybara } 
//执行后控制台将会输出:kapybara

查询键

  • 在哈希表中,没有直接通过输入值查询键的方法,所以我们只能通过遍历的方法,将哈希表中的所有键值对逐个读取一遍,直到找到对应的值后才能得到对应的键
//此处我要通过值val找出对应的键
//代码将在后文详细解释
for (const auto& p : hs) {
    if (p.second == val) {
        cout << "对应的翻译是:" << p.first << endl;
    }
}
  • 在上面的代码中,const auto 表示自动根据后面变量 p 的值推断相应的数据类型;符号 & 表示应用类型,引用类型可以避免在循环中对容器元素进行拷贝,提高性能并节省内存。
  • for (const auto& p : hs) 表示遍历循环,具体来说变量 p 将会依次等于 hs 中的每一个键值对。在循环内部,因为 p 等于键值对,而键值对包含两个变量,所以 p.firstp.second 就分别表示 p 包含的两个变量,即

在这里插入图片描述

  • 因此,当 p.second = val 的时候,p.first就等于对应的key,从而得到键。

查询键是否存在( count )

  • 我们在进行键的增删查操作时,难免会遇到键不存在的情况,如果强行调用不存在的键,程序不会报错,而是会返回一个空值
  • 但通常情况下,我们并不希望它返回空值,而是进行其他操作。所以,我们可以使用 hs.count(key)方法 来查询键是否存在。此方法的原理是返回哈希表中键与传入的 key 相同的键值对的数量,但根据键唯一的特性,此方法通常只会返回两个值,即 01
if( hs.count(key) == 0 )
    cout << "键值对不存在!";
else ( hs.count(key) == 1 )
    cout << "键值对存在!";
至此,哈希表的基本用法讲解完毕

完整代码展示

题目:使用哈希表完成以下功能:创建一个简单的中英词典,用户可以根据中文查询英文( 进阶:也可以根据英文查询中文 ),并且用户可以向词典中添加和删除内容。

#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;

//这里我将大部分哈希表的相关操作单独写在getVal方法中,以便读者单独理解
//这里哈希表hs用引用类型,防止二次拷贝,从而节省内存
void getVal(unordered_map<string, string>& hs, string key) {
    if (key[0] >= 65 && key[0] <= 122) {
        //根据英文(值)查询中文(键)
        //遍历哈希表
        for (const auto& p : hs) {
            if (p.second == key) {
                cout << "对应的翻译是:" << p.first << endl;
                return;
            }
        }
        cout << "未查询到值!" << endl;
        return;
    }
    if (hs.count(key) == 0) {  //查询指定值的数量
        cout << "未查询到值!" << endl;
        return;
    }
    //根据中文(键)查询英文(值)
    cout << "对应的翻译是:" << hs[key] << endl;
}

int main() {
    //声明一个哈希表
    unordered_map<string, string> hs;
    //向哈希表中添加一些初始数据
    hs.insert({ "蝾螈", "newt" });
    hs.insert({ "章鱼", "octopus"});
    hs.insert({ "水豚", "capybara"});
    hs.insert({ "牛蛙", "bullfrog" });
    hs.insert({ "臭鼬", "skunk" });
    cout << "输入\"退出\"退出程序,输入\"删除\"删除单词,输入\"增加\"增加单词" << endl;
    while (true) {
        cout << "输入查询的单词:";
        string s; cin >> s;
        if (s == "删除") {
            //此处仅举例根据键删除,若要根据值删除同理遍历哈希表即可
            cout << "请输入要删除的单词的中文:";
            cin >> s;
            hs.erase(s);
            cout << "已删除!" << endl;
        }
        else if (s == "退出")
            break;
        else if (s == "增加") {
            //将用户输入的字符串作为参数传递给insert
            cout << "请输入中文:";
            string chinese; cin >> chinese;
            cout << "请输入英文:";
            string english; cin >> english;
            hs.insert({ chinese, english });
            cout << "已添加!" << endl;
        }
        else 
            getVal(hs, s);
    }
    return 0;
}
如需提问,可以在评论区留言或私信(=
感谢您的阅读(=

by.Qin3Yu

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图扑物联 | WEB组态可视化软件

什么是组态&#xff1f; 组态的概念来自于20世纪70年代中期出现的第一代集散控制系统&#xff08;Distributed Control System&#xff09;&#xff0c;可理解为“配置”、“设置”等&#xff0c;是指通过人机开发界面&#xff0c;用类似“搭积木”的简单方式来搭建软件功能&a…

数据可视化---饼图、环形图、雷达图

类别内容导航机器学习机器学习算法应用场景与评价指标机器学习算法—分类机器学习算法—回归机器学习算法—聚类机器学习算法—异常检测机器学习算法—时间序列数据可视化数据可视化—折线图数据可视化—箱线图数据可视化—柱状图数据可视化—饼图、环形图、雷达图统计学检验箱…

云服务器部署vue/node项目

此处以阿里云服务器为例&#xff0c;配置的是LNMP环境 vue部署云服务器&#xff1a; 以阿里云服务为例&#xff0c;端口自定义99 1、在 /usr/share/nginx/html/ 该目录下新建文件夹&#xff0c;该文件夹是部署的打好包的前端项目 例&#xff1a; 2、进入nginx目录配置相关配…

html+css+javascript实现渐隐轮播

实现效果&#xff1a; 图片自动轮播&#xff0c;点击左右按钮会操作图片向前或向后&#xff0c;图片与小圆点相互呼应&#xff0c;具有交互效果。 编写思想&#xff1a; 实现交互时使用了排他思想&#xff0c;同选项卡的功能&#xff1b; 自动轮播采用了setInterval()&#…

C++ summary 工具 Insights: 源码工具:应用篇 inline函数

介绍篇 在线执行 悬停&#xff0c;显示帮助 右键&#xff0c;查看文档 template example_1 int main(){int a 123;return 0; }(gdb) disas Dump of assembler code for function main():0x0000555555555129 <0>: endbr64 0x000055555555512d <4>: push …

2023年【陕西省安全员C证】新版试题及陕西省安全员C证复审模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 陕西省安全员C证新版试题参考答案及陕西省安全员C证考试试题解析是安全生产模拟考试一点通题库老师及陕西省安全员C证操作证已考过的学员汇总&#xff0c;相对有效帮助陕西省安全员C证复审模拟考试学员顺利通过考试。…

C#有望成为2023年的编程语言之王

前言 TIOBE 2023年12月编程语言指数头条新闻&#xff1a;C#有望成为2023年的编程语言之王。 TIOBE是什么&#xff1f; 访问地址&#xff1a;https://www.tiobe.com/tiobe-index/ TIOBE是一个编程社区指数&#xff0c;用于衡量不同编程语言的受欢迎程度。TIOBE指数基于全球范围…

接口自动化测试框架【AIM】

最近在做公司项目的自动化接口测试&#xff0c;在现有几个小框架的基础上&#xff0c;反复研究和实践&#xff0c;搭建了新的测试框架。利用业余时间&#xff0c;把框架总结了下来。 AIM框架介绍 AIM&#xff0c;是Automatic Interface Monitoring的简称&#xff0c;即自动化…

pytest之allure测试报告02:allure具体使用方法

一、allure包含的方法 二、allure使用教程 &#xff08;1&#xff09;用例中写入allure方法 allure.epic("数据进制项目epic") allure.feature("手机号模块feature") class TestMobile:allure.story("杭州的手机号story")allure.title("测…

桌面概率长按键盘无法连续输入问题

问题描述&#xff1a;概率性长按键盘无法连续输入文本 问题定位&#xff1a; 系统按键流程分析 图一 系统按键流程 按键是由X Server接收的&#xff0c;这一点只要明白了X Window的工作机制就不难理解了。X Server在接收到按键后&#xff0c;会转发到相应程序的窗口中。在窗…

单片机——通信协议(UART协议解析篇)

一、引言 在嵌入式系统设计中&#xff0c;UART通信是一种广泛使用的串行通信协议&#xff0c;它通过两条信号线实现全双工的数据传输和接收。UART通信协议以其简单、灵活和易于集成的特点&#xff0c;在嵌入式设备之间以及与外部设备进行通信时发挥着重要作用。本文将详细介绍U…

VS Code连接远程Linux服务器调试C程序

1.在 VS Code 上安装扩展 C/C 2.通过 VS Code 连接远程 Linux 服务器 3.通过 VS Code 在远程 Linux 服务器上安装扩展 C/C 4.打开远程 Linux 服务器上的文件夹 【注】本文以 /root/ 为例。 5.创建项目文件夹&#xff0c;并在项目文件夹下创建C程序 6.按 F5&#xff0c;选…

浅显易懂 @JsonIgnore 的作用

1.JsonIgnore作用   在json序列化/反序列化时将java bean中使用了该注解的属性忽略掉 2.这个注解可以用在类/属性上   例如&#xff1a;在返回user对象时&#xff0c;在pwd属性上使用这个注解&#xff0c;返回user对象时会直接去掉pwd这个字段&#xff0c;不管这个属性有没…

Linux Shell——(脚本参数传递)

脚本参数传递 一、参数传值二、脚本文件中特殊的变量 总结 最近学习了shell脚本&#xff0c;记录一下shell脚本参数传递相关语法 一、参数传值 执行脚本的时候&#xff0c;可以向脚本传递参数&#xff0c;脚本内获取参数的格式为$n n位置从1开始&#xff0c;$0 是脚本的文件名…

(代码详解)绘制气泡图+详细讲解图例设置+如何正确理解气泡图+气泡大小、颜色+调参

目录 气泡图简介&#xff1a; 一、导入库 二、准备数据 三、画气泡图--基础版 四、画气泡图--进阶版一 (控制气泡大小) 解读气泡图&#xff1a; 五、画气泡图--进阶版二(控制气泡颜色) (一)用参数c控制气泡颜色 (二)用for循环的方法控制气泡颜色 (三)给气泡分配指定的颜…

FFmpeg——在Vue项目中使用FFmpeg(安装、配置、使用、SharedArrayBuffer、跨域隔离、避坑...)

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

Kali Linux安装Xrdp远程桌面工具结合内网穿透实现远程访问Kali桌面

文章目录 前言1. Kali 安装Xrdp2. 本地远程Kali桌面3. Kali 安装Cpolar 内网穿透4. 配置公网远程地址5. 公网远程Kali桌面连接6. 固定连接公网地址7. 固定地址连接测试 前言 Kali远程桌面的好处在于&#xff0c;它允许用户从远程位置访问Kali系统&#xff0c;而无需直接物理访…

韩顺平学java第二阶段之BS框架002

这边讲了php都可以&#xff0c;反正就是打通双方的间隔就行了∑(っД;)っ卧槽&#xff0c;不见了

sap table 获取 valuation class MBEW 查表获取

参考 https://www.tcodesearch.com/sap-tables/search?qvaluationclass

尚硅谷Docker笔记-基础篇

B站视频&#xff1a;https://www.bilibili.com/video/BV1gr4y1U7CY 1.Docker简介 解决了运行环境和配置问题的软件容器 方便做持续集成并有助于整体发布的容器虚拟化技术 容器与虚拟机比较 Docker 容器是在操作系统层面上实现虚拟化&#xff0c;直接复用本地主机的操作系统…