一文帮你弄懂散列是什么

什么是散列?

我们先看这样一个问题:给出N个正整数,再给出M个正整数,问你M中出现的每个数是否在N中出现过。其中N,M<=10³。

最直观的思路就是暴力枚举,先在M中挑一个数,然后和N中的数一一比较,比较完了之后再在M中挑第二个数,以此类推。但是这样的复杂度达到了O(MN),是不优秀的算法。

不妨用空间换时间,让M个整数做为数组的下标建立数组。比如M个数分别为5,9,12,7,N个数分别为9,7,12,6。那么先建立bool数组hashtable[Maxn]={false},然后遍历9,7,12,6这几个下标对应的值由false改为true,然后再去遍历5,9,12,7,但是遍历的同时加一句hashtable[x]是否为true,来判断是否出现过。

bool hashtable[10000]={false};
int mian(){
	int n,m,x;
	scanf{"%d%d",&n,&m};
	for(int i=0;i<n;i++){
		scanf("%d",&x);
		hashtable[x]=true;  //数字x出现过
	}
	for(int i=0;i<m;i++){
		scanf("%d",&x);
		if(hashtable[x]==true)
			printf("yes\n");
		else
			printf("no\n");
	}
	return 0;
}

如果问M个欲查询的数中每个数在N个数中出现的次数,则可以把hashtable数组转为int型,每次出现了则++。(自己动手试一试)

以上题目都是直接把输入的数作为数组的下标来进行统计(非常实用!),假如我们要统计一篇英文文章中love字符串出现的次数该怎么办呢?那我们就用love做下标来统计咯。但是一般来说只有整数才可以做下标,怎么办?于是我们就要用到散列的思想。

散列官方含义是“将元素通过一个函数转化为整数,使得该整数可以尽量唯一地代表这个元素。”

通俗点就是,将元素化为一个唯一能表示它的整数,以后见到这个整数就相当于见到见到了该元素,那么我拿这个整数做下标实际上就是拿这个字符做下标,根据这个思想,岂不是万物皆可做下标。

常用的方法有:除留余数法、线性探查法、平方探查法、链地址法等,这些方法不再此处细讲,因为接下来要讲的可以省去这一步。

C++中有个map库,就可以让字符直接做下标,电脑已经帮我们对这些字符进行了哈希处理(也就是散列处理,因为散列的英文是hash),我们接下来看到题来实践一下。

题目: 到底买不买
问题描述:小红想买些珠子做一串自己喜欢的珠串。卖珠子的摊主有很多串五颜六色的珠子,但不肯把任何一串拆开卖。于是小红请你帮忙判断,某串珠子是否包含了全部自己想要的珠子?如果是,告诉她有多少多余的珠子,如果不是,告诉她缺少了多少珠子。
分析:这里用09,az,A~Z范围内的字符表示颜色。
输入格式:每个测试用例分别再两行中先给出摊主珠子和小红想买做的珠串,两串都不超过1000个珠子。
输出格式:如果可以买,则输出YES以及有多少个多余的珠子;如果不可以,则在一行中输出NO以及缺了多少珠子。期间用一个空格分隔。
输入用例:
ppRYYGrrYBR2258
YrR8RrY
输出样例:
YES 8

思路分析:将老板的珠子放入哈希表中,以珠子颜色为键,珠子数量为值,形成键值对,然后拿小红所需要的珠子颜色为键去访问老板的珠子哈希表,如果有,则老板珠子哈希表对应的值就减一,没有,缺的珠子就加一,最后,如果缺的珠子大于0,说明不可以买,并输出缺的珠子,如果缺的珠子等于0(即没缺珠子),那么这个时候老板的珍珠数量减去小红的珍珠数量就是多余的珍珠数量。

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

int main() {
	int lack=0,surplus=0;
	string boss;
	string hong;
	cin >> boss;
	cin >> hong;
	map<char, int> pearl;//哈希表没有键值对的地方就是0-0
	for (int i = 0; i < boss.length(); i++) {
		pearl[boss[i]]++;
	}
	for (int i = 0; i < hong.length(); i++) {
		if (pearl[hong[i]] == 0)
			lack++;
		else
			pearl[hong[i]]--;//相当于把珠子给了小红,然后摊主的珠子减一,防止后面小红要好多颗珍珠,摊主就只有一颗珍珠在这里唬人
	}
	surplus = boss.length() - hong.length();
	if (lack > 0)
		cout << "NO!!" << "  " << lack << endl;
	else
		cout << "YES!!" << "  "<< surplus  <<endl;
	return 0;
}

相信看到这你已经弄懂了什么是散列,并且知道怎么去运用了,一定要多动手实践一下。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F103是意法半导体(STMicroelectronics)推出的一款32位单片机系列,属于Cortex-M3内核。下面是一份简要的说明,助你了解STM32F103。 1. 内核架构:STM32F103采用ARM Cortex-M3内核,具有较高的性能和低功耗特性。它运行在最高72MHz频率下。 2. 存储器:STM32F103具有不同的存储器选项,包括闪存(Flash)和随机存取存储器(SRAM)。闪存用于存储程序代码和常量数据,SRAM用于存储变量和堆栈。 3. 外设:STM32F103拥有丰富的外设,包括通用定时器、串行通信接口(USART、SPI、I2C)、模数转换器(ADC)、通用输入输出引脚(GPIO)等。这些外设可用于实现各种应用,如控制、通信和传感器接口。 4. 开发环境:对于STM32F103的开发,你可以使用ST提供的官方开发工具——STM32CubeIDE,它是基于Eclipse的集成开发环境。此外,你还可以使用其他第三方软件,如Keil MDK或IAR Embedded Workbench。 5. 编程语言:你可以使用C/C++编程语言进行STM32F103的开发。ST提供了丰富的库函数和示例代码,方便开发者快速上手。 6. 资源:为了更好地了解STM32F103,你可以参考ST官方的技术文档、数据手册和应用笔记。此外,CSDN等网站上也有很多关于STM32F103的教程和案例供你学习参考。 需要注意的是,上述信息只是对STM32F103的一个简要介绍,如果你希望深入了解它的特性和开发方法,建议你查阅更多资料并进行实际的开发练习。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值