算法十一——散列表hash(牺牲空间换时间,提高查找速度)附数字查找hash题、变变式题——字符串出现次数

时间效率

在平均情况下,散列表执行各种操作的时间都为O(1)。O(1)被称为常量时间。你以前没有见过常量时间,它并不意味着马上,而是说不管散列表多大,所需的时间都相同
在这里插入图片描述
这意味着无论散列表包含一个元素还是10亿个元素,从其中获取数据所需的时间都相同。实际上,你以前见过常量时间——从数组中获取一个元素所需的时间就是固定的:不管数组多大,从中获取一个元素所需的时间都是相同的。在平均情况下,散列表的速度确实很快。
在这里插入图片描述

例一、

在这里插入图片描述

对应的C++代码如下:

#include<iostream>
#include<string>
#include<unordered_map>
#include<utility> 

using namespace std;

int main()
{
	unordered_map<string, float> book = {
		{"apple", 0.67}, 
		{"milk", 1.49},
		{"avocado", 1.49}
	};
	
	for(pair<string, float> pair : book){
		cout << pair.first << ":" << pair.second << "$" << endl;
	}
	return 0;
}

运行结果如下:
在这里插入图片描述

例二、

在这里插入图片描述
详细C++代码如下:

#include<iostream>
#include<unordered_map>
#include<string>

using namespace std;

unordered_map<string, bool> voted;

void check_voter(const string &name)
{
	auto search = voted.find(name);
	if(search == voted.end() || search->second == false){
		voted.insert({name, true});
		cout << "Let them vote!" << endl;
	}
	else{
		cout << "Kick them out!" << endl; 
	}
}

int main()
{
	check_voter("Tom");
	check_voter("Mike");
	check_voter("Mike");
	return 0;
}

运行结果如下:
在这里插入图片描述
有些朋友可能看得懂这些代码,但是对于头文件以及相关的函数不是很了解,这里做一些简单的解释说明

unordered_map以及相关应用

  • 相关头文件
    在这里插入图片描述
  • pair标准类型定义在头文件“#include<utility>”中,一个pair保存两个数据成员。类似容器,pair是一个用来生成特定类型的模板。当创建一个pair时,用户必须提供两个类型名,pair的数据成员将具有对应的类型。一般来说,一个pair类型的对象,其实存储的是一个键值对(key-value)。在没有对pair类型的对象进行初始化时,pair的默认构造函数对数据成员进行值初始化。用户也可以为每个成员提供初始化器: 在这里插入图片描述
  • pair的数据成员是public的,并且成员命名为first和second,用户可以使用普通的成员访问符“.”来进行访问。在这里插入图片描述
  • find()操作返回指向元素的迭代器,如果元素不存在,则返回end迭代器

Conclusion

在这里插入图片描述

数字查找hash题

题目描述

m个整数中是否有若干整数同时存在于n个整数当中,其中N,M <= 105
时间复杂度为O(N + M)

C++代码

#include<cstdio>
const int maxn = 100010;
bool hashTable[maxn] = {false};		//初始化为false 

int main()
{
	int n, m, x;
	scanf("%d%d", &n, &m);
	for(int i = 0; i < n; i++)
	{
		scanf("%d", &x);
		hashTable[x] = true;
	}
	
	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个数中出现的个数

C++代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int hashTable[maxn] = {0};

int main()
{
	int n, m, x;
	cin >> n >> m;
	for(int i = 0; i < n; i++)
	{
		cin >> x;
		hashTable[x]++;
	}
	
	for(int i = 0; i < m; i++)
	{
		cin >> x;
		cout << hashTable[x] << endl;
	}
	return 0;
}

样例运行结果:
在这里插入图片描述

变变式题——字符串出现次数

题目描述

输入n个3个大写字母的字符串;
输入m个查询字符串;
输出对应查询字符串在n个字符串中出现的次数。

C++代码

#include<bits/stdc++.h>
using namespace std;
 
const int maxn=100;
char S[maxn][5];
char temp[5];
 
int hashTable[26 * 26 * 26 + 10];
 
int hashFunc(char S[], int len)		//hash函数 
{
	int id = 0;
	for(int i = 0; i < len; i++)
	{
		id= id * 26 + (S[i] - 'A');		
	}
	return id;
}
 
int main()
{
	int n, m;
	cin >> n >> m;
	
	for(int i = 0; i < n; i++)
	{
		cin >> S[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[id] << endl;
	}
	return 0;
}

样例运行结果:
在这里插入图片描述

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值