《算法笔记》总结No.4——散列

news2024/10/6 8:22:36

        散列的英文名是hash,即我们常说的哈希~该知识点在王道408考研的教材里面属于查找的范围。即便各位并无深入了解过,也听说过散列是一种更高效的查找方法。


一.引例

先来考虑如下一个假设:设有数组M和N分别如下:

M[10]=[1,2,3,4,5,6,7,8,9,10];

N[10]=[11,12,13,14,15,16,17,18,19,20];

        M和N都是大小为10的一维数组。现在要求判断M中的整数是否在N中出现过,那么最简单暴力的一个办法就是把M中的每一个元素都在N中遍历一遍,由于M和N都是10个,因此一共要执行100次。

        不难发现——上述操作主打一个繁琐:当M和N的长度均为10000时,则需要操作1亿次——毫无疑问这是不可取的,且不说总量有多大,如果有相同的数出现,岂不是做了很多重复的步骤? 

        因此不妨考虑用空间换取时间:新开辟一个数组hashTable[10000],用来表示N中的元素是否存在——存在时即为true,不存在则赋值为false。这样如果一开始的时候就将N遍历一遍,把hashTable中的元素赋值后,M直接在hashTable中查找元素是否存在即可!


听起来有些抽象,那么举个例子直观感受一下:就拿长度为10的M和N举例:

#include <iostream>
#include <cstdio> 
using namespace std;
  
bool hashTable[10000]={ false };
//一开始所有元素均为false——不存在 
int main(int argc, char** argv) {
	//第一个循环直接用来保存N 
	for(int i=1;i<=10;i++)
	{
		int temp=0;
		cin>>temp;
		hashTable[temp]=true; //输入的元素标识为存在 
	}
	for(int i=1;i<=10;i++)
	{
		int temp=0;
		cin>>temp;
		if(hashTable[temp]==true)   //如果true即为存在 
			cout<<temp<<"在N中出现过!"<<endl; 
		else
			cout<<temp<<"在N中没出现!"<<endl;
	}
}

测试结果如下:

        来分析一下:由于存放和查找是两个独立的循环,复杂度为n+n即为2n——在这里为20。 相比暴力搜索这种100的量级还是便捷了不少,事实上当出现重复元素时可以进一步细分~

扩展:如果此处要求统计出现的次数,直接将类型改为int,然后赋值为true变成自增即可

        不难发现,上述引例中,是将元素直接作为下标来标记的——即7出现N[7]变为true,25出现N[25]变为true。这当然是非常实用且巧妙的一种做法。当下标超出、或者是元素为abcde时,这种方法就不凑效了。这时候就需要我们的散列~ 

二.整数散列

        散列的本质或者说定义可以浓缩为一句话:将元素通过一个函数转换为一个整数,使得该整数可以尽量唯一的代表这个元素。这个转换函数被称为散列函数~


常见的散列函数取法:

  • 直接定址法:恒等变换(即将key的值作为下标值),线性变换(x=a*key+b)。
  • 平方取中法:很少用,即取key值平方的中间若干位作为hash值。
  • 除留取余法: 很常用,即H(key)=key%mod,通过这种散列函数,可以把很大的数转换为不超过mod的整数,这样就可以将他作为可行的数组下标!不过表长TSize一定要大于mod,不然显而易见会发生越界。此外,当mod是一个素数时,显而易见空间可以尽可能的覆盖下标的值。为了方便起见,一般来说mod的值与TSize相等。

        当然,很明显会存在两个不同的key1和key2——他们的哈希值H(key1)、H(key2)有可能是相同的,当其中一个占领了目标单元格,另一个显而易见不能使用——这种情况被称之为冲突。以下为三种解决冲突的常见方法:

1.开放定址法

A.线性探测法

        当目标的H(key)被占领时,直接检查下一个位置即H(key)+1上的位置是否被占,如果还被占就继续寻找n+1,以此类推;如果超过了表长,就回到首位继续循环,直到所有位置都被占用。该种方法会导致扎堆,会一定程度上降低效率。

B.平方探测法

为了避免扎堆现象,发生冲突后将依次查找如下位置:H(key)+1^2,H(key)-11^2,H(key)+2^2,以此类推。如果超出表长,则对表长完成取模;如果为负数,则对结果不断加表长直到出现第一个非负数。

如果在0~TSize范围内都无法找到位置,当k大于表长时,也一定无法找到位置。

2.链地址法(拉链法) 

不计算新的hash值,而是把所有H(key)相同的key连接成一条单链表。

三.字符串散列

给出N个由3位大写字母组成的字符串,再给出M个查询字符串,问每个字符串在N个字符串中出现的次数。

#include <iostream>
#include <cstdio> 
using namespace std;
  
const int maxn=100;
char S[maxn][5],temp[5];
int hashTable[26*26*26+10];

int hashFunc(char S[],int len)
{
	int id=0;
	for(int i=0;i<len;i++)
		id=id*26+(S[i]-'A');
	return id;	
} 

int main(int argc, char** argv) {
	int n,m;
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		int id=hashFunc(S[i],3);
		hashTable[id]++;
	}
	for(int i=0;i<m;i++)
	{
		cin>>temp;
		int id=hashFunc(temp,3);
		cout<<hashTable[i]<<endl;
	}
}

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

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

相关文章

idea 默认路径修改

1.查看 idea 的安装路径&#xff08;右键点击 idea 图标&#xff0c;查看路径 &#xff09; “C:\Program Files\JetBrains\IntelliJ IDEA 2021.3.1\bin\idea64.exe” 在 bin 目录查看 idea.properties 文件&#xff0c;修改以下四个路径文件 # idea.config.path${user.home}/…

对话大模型Prompt是否需要礼貌点?

大模型相关目录 大模型&#xff0c;包括部署微调prompt/Agent应用开发、知识库增强、数据库增强、知识图谱增强、自然语言处理、多模态等大模型应用开发内容 从0起步&#xff0c;扬帆起航。 基于Dify的QA数据集构建&#xff08;附代码&#xff09;Qwen-2-7B和GLM-4-9B&#x…

QT入门笔记-自定义控件封装 30

具体代码如下: QT core guigreaterThan(QT_MAJOR_VERSION, 4): QT widgetsCONFIG c17# You can make your code fail to compile if it uses deprecated APIs. # In order to do so, uncomment the following line. #DEFINES QT_DISABLE_DEPRECATED_BEFORE0x060000 …

uni-app使用ucharts地图,自定义Tooltip鼠标悬浮显示内容并且根据@getIndex点击事件获取点击的地区下标和地区名

项目场景&#xff1a; uni-app使用ucharts地图,自定义Tooltip鼠标悬浮显示内容并且根据getIndex点击事件获取点击的地区下标和地区名 例如&#xff1a; 问题描述 官方给的文档有限&#xff0c;需要自己下载地图json数据然后自己渲染和编写鼠标悬浮显示内容以及获取点击地址…

【ComfyUI节点】扰动注意力引导Perturbed Attention Guidance

扰动注意力引导 Perturbed Attention Guidance GitHub - KU-CVLAB/Perturbed-Attention-Guidance: Official implementation of "Perturbed-Attention Guidance" 按照官方介绍&#xff0c;扰动注意力指导显著提高了扩散模型的样本质量&#xff0c;而无需外部条件&am…

代码随想录第45天|动态规划

300.最长递增子序列 参考 dp[i] 表示以 i 为结尾的最长递增子序列长度递推公式: 使用 i 和 j 判断 dp[i] max(dp[j] 1, dp[i])每次 j 都需要从头遍历 初始化: dp[i] 1 class Solution { public:int lengthOfLIS(vector<int>& nums) {vector<int> dp(nums…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【明文导入密钥(C/C++)】

明文导入密钥(C/C) 以明文导入ECC密钥为例。具体的场景介绍及支持的算法规格 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 指定密钥别名keyAlias。 密钥别名的最大长度为64字节。 封装密钥属性集和密钥材料。通过[OH_Huks_I…

实现antd designable平台的组件拖拽功能

平台&#xff1a;designable设计器 github&#xff1a;designable 目录 1 背景2 技术栈3 组件拖拽和放置3.1 类型定义3.2 拖拽3.3 放置 1 背景 由于业务需求&#xff0c;我们需要实现designable平台的一个简易版的组件拖拽功能。 #mermaid-svg-QrxSDGe9YyGG3LbQ {font-family:…

andboxie-Plus - 知名沙盒软件、支持游戏多开测试软件

我们经常会需要用到一些毒瘤软件——它们可能不是真正的恶意软件&#xff0c;但总爱偷摸干一些流氓行为。 工作中&#xff0c;有时还不得不安装使用一些来路不明、不能完全信任的可疑软件。 装上吧&#xff0c;心里膈应、难受&#xff1b;不装吧&#xff0c;有些工作又进行不…

SQLite 嵌入式数据库

目录&#xff1a; 一、SQLite 简介二、SQLite 数据库安装1、安装方式一&#xff1a;2、安装方式二&#xff1a; 三、SQLite 的命令用法1、创建、打开、退出数据库&#xff1a;2、编辑数据库&#xff1a; 四、SQLite 的编程操作1、打开 / 创建数据库的 C 接口&#xff1a;2、操作…

【数据结构与算法】快速排序双指针法

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注 ​

工程文件参考——CubeMX+LL库+SPI主机 阻塞式通用库

文章目录 前言CubeMX配置SPI驱动实现spi_driver.hspi_driver.c 额外的接口补充 前言 SPI&#xff0c;想了很久没想明白其DMA或者IT比较好用的方法&#xff0c;可能之后也会写一个 我个人使用场景大数据流不多&#xff0c;如果是大批量数据交互自然是DMA更好用&#xff0c;但考…

【Java12】封装

封装&#xff08;Encapsulation&#xff09;是面向对象的三大特征之一&#xff08;另两个是继承和多态&#xff09;&#xff0c;指的是将对象的状态信息隐藏在对象内部&#xff0c;不允许外部程序直接访问对象的内部信息&#xff0c;而是通过该类所提供的方法来实现对内部信息的…

期末成绩老师怎么发?

期末考试的钟声终于敲响&#xff0c;学生们紧张而期待地等待着成绩的揭晓。而作为老师&#xff0c;我们面临的不仅仅是成绩的评判&#xff0c;还有一项看似简单却极其繁琐的任务——将成绩单一一私信给每位学生的家长。在成绩公布的那一刻&#xff0c;我们不仅要确保每一份成绩…

CDNOW_master.txt数据分析实战

一、数据详情 该数据集是常见的销售数据集&#xff0c;数据展示的是美国1997后的商品销售数据。包含四个字段&#xff0c;分别是用户id,购买时间&#xff0c;销售量&#xff0c;与销售金额。 二、数据读取与数据清洗 导入必要的包 \s代表的许多空格作为分割&#xff0c;names重…

kafka-3

Kafka 消费组 consumer-offsets-N 稀疏索引 Kafka集群 集群搭建 集群启动和验证 Topic的意义 Topic和Partition 分区 副本 集群操作指令 多分区&多副本 多分区消费组 Rebalance机制 Rebalance机制处理流程 Rebalance机制-Range Rebalance机制-RoudRobin Rebalance机制-St…

PyQt5开发笔记:2. 2D与3D散点图、水平布局和边框修饰

一、装pyqtgraph和PyOpenGL库 pip install pyqtgraph pip install PyOpenGL 注意&#xff1a;一定不要pip install OpenGL&#xff0c;否则会找不到 二、3D散点图效果 import pyqtgraph as pg import pyqtgraph.opengl as gl import numpy as np# 创建应用程序 app pg.mkQ…

护网在即,助力安服仔漏洞扫描~

整合了个漏扫系统&#xff0c;安服仔必备~ 使用场景 网前布防&#xff0c;漏洞扫描&#xff0c;资产梳理 使用方法&#xff1a; 启动虚拟机后运行命令&#xff1a; ./StartSystemScript.sh 输入密码attack 启动完成后浏览器打开网站&#xff1a; http://IP:5000 相关账户…

【Rust基础入门】Hello Cargo

文章目录 前言Cargo是什么&#xff1f;Cargo的作用查看cargo版本使用cargo创建项目Cargo.toml文件cargo build命令cargo runcargo check为发布构建 总结 前言 在Rust编程中&#xff0c;Cargo扮演着至关重要的角色。它是Rust的包管理器&#xff0c;负责处理许多任务&#xff0c…

JAVA之(方法的重载与重写、this关键字、super关键字)

方法的重载与重写 一、方法的重载与重写1、回顾方法的定义2、重载的概念3、重写 二、this关键字1、何为this方法2、使用方法&#xff08;1&#xff09;在构造方法中指构造器所创建的新对象&#xff08;2&#xff09; 方法中指调用该方法的对象&#xff08;3&#xff09; 在类本…