c++哈希表——超实用的数据结构

news2025/1/16 20:13:06

文章目录

  • 1. 概念引入
    • 1.1 整数哈希
      • 1.1.1 直接取余法。
      • 1.1.2 哈希冲突
        • 1.1.2.1 开放寻址法
        • 1.1.2.2 拉链法
    • 1.2 字符串哈希
  • 3.结语

1. 概念引入

  • 哈希表是一种高效的数据结构 。
  • H a s h Hash Hash表又称为散列表,一般由 H a s h Hash Hash函数(散列函数)与链表结构共同实现。
  • 散列(映射)方法是使用函数 h h h 将元素 U U U映射到表 T [ 0... m − 1 ] T[0...m-1] T[0...m1] 的下标上 ( m = O ( ∣ U ∣ ) ) (m=O(|U|)) (m=O(U))。这样以 U U U中关键字为自变量,以h为函数的运算结果。
    就是相应结点的存储地址。从而达到在 O ( 1 ) O(1) O(1)时间内就可完成查找。

1.1 整数哈希

我们以一道例题来举例:哈希表。

这道题目是这么做的:

1.1.1 直接取余法。

关键字 k k k除以 m m m,取余数作为在 H a s h Hash Hash表中的位置。
函数表达式可以写成:
哈希函数 h ( k ) = k h(k) = k h(k)=k m o d mod mod m m m
一般 m m m 选择为素数,建议选择 2 e 5 + 10 2e5+10 2e5+10

1.1.2 哈希冲突

  • H a s h Hash Hash函数把复杂信息映射到一个容易维护的值域内。
  • 值域变小,有可能造成两个不同的信息被 H a s h Hash Hash函数映射为相同的值(两数同余), H a s h Hash Hash冲突,需要处理这种情况。
1.1.2.1 开放寻址法
  • 使用 H a s h Hash Hash函数 h h h把整数 x x x映射为 h [ x ] h[x] h[x],如果 h [ x ] h[x] h[x]已经有值,说明当前查询到的地址发生了冲突
  • 如果当前地址发生冲突,就向这个地址的右边继续查询,直到遇到 N U L L NULL NULL或值 x x x为止。

代码:

#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define For(i, a, b) for(int i = a;i <= b;i++)
const int N = 2e5 + 3;
const int null = 0x3f3f3f3f;
int n, h[N];
int get(int x){
    int idx = (x % N + N) % N;
    while (h[idx] != null && h[idx] != x){
        idx = (idx == N ? 0 : idx + 1);
    }
    return idx;
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    memset(h, 0x3f, sizeof h);
    int n, x;
    string op;
    cin >> n;
    while (n--){
        cin >> op;
        cin >> x;
        if (op[0] == 'I'){
            h[get(x)] = x;
        }else{
            cout << (h[get(x)] == x ? "Yes\n" : "No\n");
        }
    }
    return 0;
}

在这里插入图片描述

1.1.2.2 拉链法
  • Hash函数设为 h ( x ) = x h(x) = x % P h(x)=x ,这里 P P P 是较大质数,但不超过数组大小 N N N
  • 这个 H a s h Hash Hash函数 h h h 把整数分为了 P P P 类( M o d P = 1 , 2 , . . . , P − 1 Mod P = 1, 2, ..., P-1 ModP=1,2,...,P1),每一类用一个单独的链表存储。
  • 查找整数 x x x 的时候,就在整数 x x x 所在类的链表里进行查找。

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
#define PII pair<int, int>
#define For(i, a, b) for(int i = a;i <= b;i++)
const int N = 2e5 + 3;
int head[N], val[N], nxt[N], idx;
void add(int x){
    int k = (x % N + N) % N;
    val[idx] = x;
    nxt[idx] = head[k];
    head[k] = idx++;
}
bool get(int x){
    int k = (x % N + N) % N;
    int res = head[k];
    while (res != -1){
        
        if (val[res] == x){
            return 1;
        }
        res = nxt[res];
    }
    return 0;
}
signed main(){
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    memset(head, -1, sizeof head);
    int n;
    cin >> n;
    while (n--){
        char op;
        cin >> op;
        int x;
        cin >> x;
        if (op == 'I'){
            add(x);
        }else{
            if (get(x)){
                cout << "Yes\n";
            }else{
                cout << "No\n";
            }
        }
    }
    return 0;
}

在这里插入图片描述

1.2 字符串哈希

字符串 H a s h Hash Hash(字符串前缀 H a s h Hash Hash法),把字符串 s s s 变成一个 p p p 进制数字( H a s h Hash Hash值),实现不同的字符串映射到不同的数字。
字符串 s s s 中 的每个字符本质上就是一个数字( A S C I I ASCII ASCII值)。
s = s 0 s 1 s 2 s 3 ⋅ ⋅ ⋅ s n − 1 s = s_0 s_1s_2s_3···s_n - 1 s=s0s1s2s3⋅⋅⋅sn1
h ( s ) = s 0 ⋅ p n − 1 + s 1 ⋅ p n − 2 + ⋅ ⋅ ⋅ + s n − 1 ⋅ p 0 h(s) = s_0·p^{n-1}+s_1·p^{n-2}+···+s_n-1·p^0 h(s)=s0pn1+s1pn2+⋅⋅⋅+sn1p0

代码:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int unsigned long long
#define PII pair<int, int>
#define For(i, a, b) for(int i = a;i <= b;i++)

const int N = 1e5 + 10;
int n, m;
char s[N];
int h[N], p[N];

int get(int l, int r){
    return h[r] - h[l - 1] * p[r - l + 1];
}

signed main(){
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    cin >> n >> m >> s + 1;

    h[0] = 0;
    p[0] = 1;
    For (i, 1, n){
        
        h[i] = h[i - 1] * 131 + s[i];
        p[i] = p[i - 1] * 131;
    }

    while (m--){
        int l1, r1, l2, r2;
        cin >> l1 >> r1 >> l2 >> r2;
        if ((get(l1, r1)) == get(l2, r2)) {
            cout << "Yes\n";
        }else{
            cout << "No\n";
        }
    }
    return 0;
}

在这里插入图片描述

3.结语

今天的文章就到这里啦,三连必回哦!

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

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

相关文章

安全生产知识竞赛活动方案

为进一步普及安全生产法律法规知识&#xff0c;增强安全意识&#xff0c;提高安全技能&#xff0c;经研究&#xff0c;决定举办以“加强安全法治、保障安全生产”为主题的新修订《安全生产法》知识竞赛活动&#xff0c;现将有关事项通知如下&#xff1a; 一、活动时间&#xf…

【网络安全】网络隔离设备

一、网络和终端隔离产品 网络和终端隔离产品分为终端隔离产品和网络隔离产品两大类。终端隔离产品一般指隔离卡或者隔离计算机。网络隔离产品根据产品形态和功能上的不同&#xff0c;该类产品可以分为协议转换产品、网闸和网络单向导入产品三种。 图1为终端隔离产品的一个典型…

HTML5+CSS3②——图像、超链接、音频、视频

目录 图像 超链接 音频 视频 图像 作用&#xff1a;在网页中插入图片 单标签&#xff1a; 标签名&#xff1a;<img src"图片的URL"> <img src"图片的URL" alt"替换文本" title"提示文本"> 属性写在尖括号里面&#xff0c;…

WPF+Halcon 培训项目实战(12):WPF导出匹配模板

文章目录 前言相关链接项目专栏运行环境匹配图片WPF导出匹配模板如何了解Halcon和C#代码的对应关系逻辑分析&#xff1a;添加截取ROI功能基类矩形圆形 生成导出模板运行结果&#xff1a;可能的报错你的文件路径不存在你选择的区域的内容有效信息过少 前言 为了更好地去学习WPF…

YOLOv8改进 添加可变形注意力机制DAttention

一、Deformable Attention Transformer论文 论文地址&#xff1a;arxiv.org/pdf/2201.00520.pdf 二、Deformable Attention Transformer注意力结构 Deformable Attention Transformer包含可变形注意力机制&#xff0c;允许模型根据输入的内容动态调整注意力权重。在传统的Tra…

模型 安索夫矩阵

本系列文章 主要是 分享模型&#xff0c;涉及各个领域&#xff0c;重在提升认知。产品市场战略。 1 安索夫矩阵的应用 1.1 江小白的多样化经营策略 使用安索夫矩阵来分析江小白市场战略。具体如下&#xff1a; 根据安索夫矩阵&#xff0c;江小白的现有产品是其白酒产品&…

西北工业大学计算机组成原理实验报告——verilog前两次

说明 为了有较好的可读性&#xff0c;报告仅仅粘贴关键代码。该PDF带有大纲功能&#xff0c;点击大纲中的对应标题&#xff0c;可以快速跳转。 实验目标 掌握单周期CPU执行指令的流程和原理&#xff1b;学习使用verilog HDL语言实现单周期CPU, 并通过功能仿真&#xff1b;提…

leetcode 315. 计算右侧小于当前元素的个数(hard)【小林优质解法】

链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 代码&#xff1a; class Solution {int[]counts; //用来存储结果int[]index; //用来绑定数据和原下标int[]helpNums; //用于辅助排序 nums 数组int[]helpIndex; //用于辅助排序 i…

Javaweb之Mybatis入门的详细解析

Mybatis入门 前言 在前面我们学习MySQL数据库时&#xff0c;都是利用图形化客户端工具(如&#xff1a;idea、datagrip)&#xff0c;来操作数据库的。 在客户端工具中&#xff0c;编写增删改查的SQL语句&#xff0c;发给MySQL数据库管理系统&#xff0c;由数据库管理系统执行S…

分享好用稳定快递查询api接口(对接简单)

提供实时查询和自动识别单号信息。稳定高效&#xff0c;调用简单方便&#xff0c;性价比高&#xff0c;一条链接即可对接成功。 使用数据平台该API接口需要先注册后申请此API接口。申请成功后赠送免费次数&#xff0c;可直接在线请求接口数据。 接口地址&#xff1a;https://…

迭代归并:归并排序非递归实现解析

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《数据结构&算法》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! &#x1f4cb; 前言 归并排序的思想上我们已经全部介绍完了&#xff0c;但是同时也面临和快速排序一样的问题那就是递…

『亚马逊云科技产品测评』活动征文|云服务器如何快速搭建个人博客(图文详解)

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 文章目录 引言一、前期准备步骤1.1 准备一个亚马逊 EC2 服务器1.2 进入控…

Stimulsoft BI Designer 2024.1.2 Crack

Stimulsoft BI Designer Do you want to create reports and dashboards, but you do not need to create your application? We want to offer you a great solution – Stimulsoft Designer! All you need is to connect your data, drag it onto the template page, config…

uniapp打包Android、Ios、微信小程序

首先我们需要在我们的代码中&#xff0c;把我们所要用到的配置信息配置好&#xff0c;在检查一下我们测试的内容是否有打开&#xff08;取消注释&#xff09;&#xff0c;在检查一下我们的版本信息是否正确&#xff0c;查看一下接口ip是否是正式线 这里的配置信息一定要配置好…

二进制、位运算和掩码运算,小白鼠测试示例

1. 二进制 二进制是一种基于两个数字0和1的数制系统。它可以表示两种状态&#xff0c;即开和关。所有输入电脑的任何信息最终都要转化为二进制。目前通用的是ASCII码。最基本的单位为bit。 在计算机科学中&#xff0c;二进制是最常用的数制系统&#xff0c;因为计算机内部的所…

【MySQL】主从异步复制配置

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精…

解锁大数据世界的钥匙——Hadoop HDFS安装与使用指南

目录 1、前言 2、Hadoop HDFS简介 3、Hadoop HDFS安装与配置 4、Hadoop HDFS使用 5、结语 1、前言 大数据存储与处理是当今数据科学领域中最重要的任务之一。随着互联网的迅速发展和数据量的爆炸性增长&#xff0c;传统的数据存储和处理方式已经无法满足日益增长的需求。…

LabVIEW在大型风电机组状态监测系统开发中的应用

LabVIEW在大型风电机组状态监测系统开发中的应用 风电作为一种清洁能源&#xff0c;近年来在全球范围内得到了广泛研究和开发。特别是大型风力发电机组&#xff0c;由于其常常位于边远地区如近海、戈壁、草原等&#xff0c;面临着恶劣自然环境和复杂设备运维挑战。为了提高风电…

C语言函数篇——scanf()函数介绍

好的&#xff0c;让我们以输入/输出函数中的scanf()为例&#xff0c;来详细介绍并展示其应用案例。 scanf()函数介绍&#xff1a; scanf()函数是C语言中用于从标准输入&#xff08;通常是键盘&#xff09;读取数据的函数。它可以从用户处获取各种类型的数据&#xff0c;并将其…

11|代理(上):ReAct框架,推理与行动的协同

11&#xff5c;代理&#xff08;上&#xff09;&#xff1a;ReAct框架&#xff0c;推理与行动的协同 在之前介绍的思维链&#xff08;CoT&#xff09;中&#xff0c;我向你展示了 LLMs 执行推理轨迹的能力。在给出答案之前&#xff0c;大模型通过中间推理步骤&#xff08;尤其…