Hash表

Hash表

  • 前言
  • 存储结构
    • 链表法
      • 初始哈希表
      • 大致的思路
      • 代码讲解及实现
        • 声明
        • 插入
        • 寻找
        • 主函数
    • 开放寻址法
      • 大致的思路
      • 代码讲解及实现
        • 声明
        • find
        • 主函数
  • 实际运用
    • 字符串前缀哈希法
      • 大致思路
      • 代码实现

前言

hello! 这里是欧_aita的博客。
每日一汤:不管你做什么,都要全心全意地投入其中。这是取得成功的秘诀。
我的主页:欧_aita
欢迎大家关注我的专栏:
数据结构与算法
MySQL数据库

在这里插入图片描述

存储结构

链表法

初始哈希表

哈希表(Hash Table)是一种数据结构,它使用哈希函数来将键映射到数组的特定位置,从而实现快速的数据检索。哈希表通常是通过数组实现的,这个数组的每个位置被称为桶(bucket),而哈希函数将键映射到特定的桶。

哈希表的基本思想是通过哈希函数将键转换为数组的索引,使得可以直接访问数组中的特定位置以获取或存储数据。这样,查找、插入和删除的平均时间复杂度都可以达到常数级别(O(1))

大致的思路

在这里插入图片描述
在初始的h数组中(槽)下以链表形式存储数据。

代码讲解及实现

声明

h[N]就是上文提起的槽,而e[],ne[],idx都是为了使用数组模拟链表。

#include <iostream>
#include <cstring>
using namespace std;
const int N =100003;
int h[N],e[N],ne[N],idx;
插入

这里的k向N取模后再加N是为了得到一个非负数,在槽中,下标没有负数,在C++语法中负数取模后得到的还是负数。

void insert(int x)
{
     int k = (x % N + N) % N;
     e[idx] = k,ne[idx] = h[k],h[k] = idx++;
}
寻找
bool find(int x)
{
      int k = (x % N + N) % N;
      for(int i = h[k];i != -1;i++)
          if(e[i]==x)
             return true;
      return false;
}
主函数

使用scanf()可以忽略回车符,制表符,空格,不容易出现其他错误。

int main()
{
    int n;
    cin >> n;
    memset(h,-1,sizeof h);
    while(n--)
    {
        char op[2];
        int x;
        scanf("%s%d",op,&x);
        if(*op == 'I')insert(x);
        else 
        {
            if(find(x))puts("Yes");
            else puts("No");
        }
    }
    return 0;
}

开放寻址法

大致的思路

在这里插入图片描述
开放寻址法就是在寻找空的槽位,当y这个数据元素在寻找槽位时发现第一个槽位已满,此时发生冲突,y就会寻找下一个空槽位。

这也暴露出了开放寻址法有一个弊端,当哈希表变得拥挤,插入操作就会降低效率。

代码讲解及实现

声明

这里的0*3f3f3f3f是指无穷大的意思,大致是10^9。

不难发现此时的N相较于链表法多了一倍,解释如下:

在开放寻址法中,选择 N 取得较大的原因可能是为了避免过早的冲突。如果哈希表的大小较小,那么在插入一些元素后,就可能很快发生冲突,导致性能下降。通过选择较大的 N,可以减少冲突的可能性,延迟哈希表填满槽位的时间。

对于链表法,由于每个槽可以存储多个元素,相对较小的 N 也可能足够处理大量的元素。链表法的优势在于能够处理高度冲突的情况,而且不需要像开放寻址法那样在数组中线性搜索。

#include <iostream>
#include <cstring>
using namespace std;
const int N = 200003,null=0x3f3f3f3f;
int h[N];
find

若k==N即表示已经遍历到了槽的末端,此时将k赋值为0,从头开始。

int find(int x)
{
	int k = (x % N + N) % N;

	while (h[k] != null && h[k] != x)
	{
		k++;
		if (k == N)k = 0;
	}

	return k;
}
主函数

这里与链表法有略微的不同,就是在插入部分。
0x3f代表0。

int main()
{
	int n;
	scanf("%d", &n);

	//清空槽
	memset(h, 0x3f, sizeof h);

	while (n--)
	{
		char op[2];
		//scanf可以自动忽略空格、回车、制表符,可以提高代码的准确率
		int x;
		scanf("%s%d",op,&x);

		int k = find(x);
		if (*op == 'I')
		{
			h[k] = x;
		}
		else
		{
			if (h[k]!=null)puts("Yes");
			else puts("No");
		}
	}
	return 0;
}

在这里插入图片描述

实际运用

字符串前缀哈希法

使用Hash表判断两段字符串是否相同

大致思路

在这里插入图片描述
使用前缀和的哈希值判断这串字符串是否相等。

代码实现

#include <iostream>
#include <cstring>

//hash表,时间复杂度可以看为O(1)
//字符串前缀哈希法,用于判断两段字符串是否相等
using namespace std;

typedef unsigned long long ULL;

const int N = 200003,P=131;

int n,m;
char str[N];
ULL h[N], p[N];

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

int main()
{
	scanf("%d%d%s", &n, &m, str + 1);

	p[0] = 1;
	for (int i = 1; i <= n; i++)
	{
		p[i] = p[i - 1] * P;
		h[i] = h[i - 1] * P + str[i];
	}

	while (m--)
	{
		int l1, r1, l2, r2;
		scanf("%d%d%d%d", &l1, &r1, &l2, &r2);

		if (get(l1, r1) == get(l2, r2))puts("Yes");
		else puts("No");
	}
	return 0;
}

p[i] = p[i - 1] * P;:这一行代码计算了 P 的第 i 次幂,将结果存储在 p[i] 中。这是为了在后续计算哈希值时使用,引入了不同位置上的权值。

h[i] = h[i - 1] * P + str[i];:这一行代码计算了字符串 str 的前缀哈希值,存储在 h[i] 中。每次循环,它计算了字符串的前 i 个字符的哈希值,其中 h[i - 1] 是前 i-1 个字符的哈希值,P 是前面计算的幂次方,str[i] 是当前字符的 ASCII 码值

这篇文章就到此结束了,如果对你有所帮助就点个赞吧。

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

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

相关文章

网络相关-面试高频

网络 当前的应用系统主要分两大类&#xff0c;一类是C/S&#xff08;Client/Server&#xff09;客户端/服务器架构的&#xff0c;一类是B/S&#xff08;Browser/Server&#xff09;浏览器/服务器架构的[3]&#xff0c;例如&#xff1a;PC上安装的QQ程序是典型的C/S架构中的客户…

LeetCode(37)矩阵置零【矩阵】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 73. 矩阵置零 1.题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]…

JVM

图来自JavaGuide 程序计数器 程序计数器是线程私有的&#xff0c;每个线程一份&#xff0c;是线程安全的&#xff1b;内部保存的字节码的行号&#xff0c;用于记录正在执行的字节码指令的地址。 java堆 java堆是线程共享的区域&#xff08;线程不安全&#xff09;&#xff…

Pandas进阶:20个实用的Pandas函数的基本使用

1. ExcelWriter 很多时候dataframe里面有中文&#xff0c;如果直接输出到csv里&#xff0c;中文将显示乱码。而Excel就不一样了&#xff0c;ExcelWriter是pandas的一个类&#xff0c;可以使dataframe数据框直接输出到excel文件&#xff0c;并可以指定sheets名称。 df1 pd.Da…

玻色量子对外合作

2023年 2023.7 首个央企量子云计算项目&#xff0c;中标&#xff01; 2023.6 勇闯“量子电力”新领域&#xff0c;玻色量子与清大科越达成战略合作 2023.5 玻色量子签约移动云“五岳”量子云计算创新加速计划&#xff01; 2023.3 “量子计算通信”&#xff01;玻色量子与…

使用netconf配置华为设备

实验目的&#xff1a; 公司有一台CE12800的设备&#xff0c;管理地址位172.16.1.2&#xff0c;现在需要编写自动化脚本&#xff0c;通过SSH登陆到设备上配置netconf协议的用户名&#xff0c;密码以及netconf服务&#xff0c;并且通过netconf协议将设备的loopback0接口IP地址配…

小航助学题库蓝桥杯题库c++选拔赛(22年1月)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09; 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;

适用于 Windows 的最佳电脑数据恢复软件是什么?

数据丢失是数字世界中令人不快的一部分&#xff0c;它会在某一时刻影响许多计算机用户。很容易意外删除一些重要文件&#xff0c;这可能会在您努力恢复它们时带来不必要的压力。幸运的是&#xff0c;数据恢复软件可以帮助恢复已删除的文件&#xff0c;即使您没有备份它们。这是…

CONTROLLING VISION-LANGUAGE MODELS FOR MULTI-TASK IMAGE RESTORATION

CONTROLLING VISION-LANGUAGE MODELS FOR MULTI-TASK IMAGE RESTORATION (Paper reading) Ziwei Luo, Uppsala University, ICLR under review(6663), Cited:None, Stars: 350, Code, Paper. 1. 前言 像CLIP这样的视觉语言模型已经显示出对零样本或无标签预测的各种下游任务…

fastadmin 如何引入自己的js

在需要的界面中&#xff1a;如何实例说明&#xff1a; 中<script> function zhuruJs(url) { let temp document.createElement( script ); temp.setAttribute( type, text/javascript" );temp.src urL; document.head . appendChild(temp); zhuruJs(location…

智能优化算法应用:基于哈里斯鹰算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于哈里斯鹰算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于哈里斯鹰算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.哈里斯鹰算法4.实验参数设定5.算法结果6.参考…

【Hydro】SG滤波器纯numpy实现

目录 说明WIKI示例滑动平均卷积系数的推导第一点和最后点的处理scipy.signal中的savgol_filter纯numpy实现的savgol_filterCPP实现的savgol_filter参考文献说明 Savitzky-Golay滤波器(S-G滤波器)是一种在时域和频域上同时进行的滤波方法,它通过局部多项式拟合来平滑信号。这…

ExoPlayer - Failed to initialize OMX.qcom.video.decoder.avc

人莫鉴于流水而鉴于止水&#xff0c;唯止能止众止 1. 背景 使用ExoPlayer&#xff0c;我不信你没遇到过这个问题&#xff1a; java.lang.IllegalArgumentException: Failed to initialize OMX.qcom.video.decoder.avc 详细内容如下图所示&#xff1a; 2. MediaCodec(解码器) …

Android控件全解手册 - 多语言切换完美解决方案(兼容7.0以上版本)

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

MySQL-函数

一、统计函数 CREATE TABLE student (id INT NOT NULL DEFAULT 1,name varchar(20) not null default ,chinese float not null default 0.0,english float not null default 0.0,math float not null default 0.0 );insert into student values (1,曹操,77,89,85);insert int…

Python内置函数与标准库函数的详细解读

一、内置函数与标准库函数的区分 Python 解释器自带的函数叫做内置函数&#xff0c;这些函数可以直接使用&#xff0c;不需要导入某个模块。 Python 解释器也是一个程序&#xff0c;它给用户提供了一些常用功能&#xff0c;并给它们起了独一无二的名字&#xff0c;这些常用功能…

二叉树leetcode(求二叉树深度问题)

today我们来练习三道leetcode上的有关于二叉树的题目&#xff0c;都是一些基础的二叉树题目&#xff0c;那让我们一起来学习一下吧。 https://leetcode.cn/problems/maximum-depth-of-binary-tree/submissions/ 看题目描述是让我们来求出二叉树的深度&#xff0c;我们以第一个父…

【LeetCode刷题】--90.子集II

90.子集II class Solution {public List<List<Integer>> subsetsWithDup(int[] nums) {List<List<Integer>> ans new ArrayList<>();List<Integer> list new ArrayList<>();//排序后便于去重Arrays.sort(nums);dfs(0,nums,ans,lis…

Docker的数据持久化;Docker网络;Dockerfile编写

Docker的数据持久化&#xff1b;Docker网络&#xff1b;Dockerfile编写&#xff1b; 文章目录 Docker的数据持久化&#xff1b;Docker网络&#xff1b;Dockerfile编写&#xff1b;**Docker的数据持久化**1&#xff09;将本地目录映射到容器里2&#xff09;数据卷3&#xff09;将…

聚类分析例题 (多元统计分析期末复习)

例一 动态聚类&#xff0c;K-means法&#xff0c;随机选取凝聚点&#xff08;题目直接给出&#xff09; 已知5个样品的观测值为&#xff1a;1&#xff0c;4&#xff0c;5&#xff0c;7&#xff0c;11。试用K均值法分为两类(凝聚点分别取1&#xff0c;4与1&#xff0c;11) 解&…