首页 > 其他分享 >Hash入门

Hash入门

时间:2024-09-20 22:52:20浏览次数:3  
标签:index set Hash 入门 tables map 哈希 unordered

unordered_set

void test_unordered_set()
{
	unordered_set<int> us;
	us.insert(4);
	us.insert(2);
	us.insert(1);
	us.insert(5);
	us.insert(6);
	us.insert(2);
	us.insert(2);
	//去重
	unordered_set<int>::iterator it = us.begin();
	while (it != us.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

unordered_set:可以做到去重+排序。

set:可以做到排序+去重。

unordered_map

void test_unordered_map()
{
	unordered_map<string, string> dict;
	dict.insert(make_pair("sort", "排序"));
	dict["string"] = "字符串";
	dict.insert(make_pair("left", "左边"));
	unordered_map<string, string>::iterator dit = dict.begin();
	while (dit != dict.end())
	{
		cout << dit->first << " : " << dit->second << endl;
		++dit;
	}
	cout << endl;
}

unordered_map按插入的顺序输出,map会先根据key排序然后再输出。

总结:

map和set和unordered_map/unordered_set的区别和联系

1.都可以实现key和key/value的搜索场景,功能和使用基本一样

2.map/set底层是红黑树实现的遍历后是有序的,增删查改的时间复杂都为O(logN)

3.unordered_map/unordered_set的底层是使用哈希表实现的,遍历出来是无序的,增删查改的时间复杂都为O(l)

4.map/set是双向迭代器,unordered_map/unordered_set是单向迭代器。

961. 在长度 2N 的数组中找出重复 N 次的元素

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=O83Ahttps://leetcode.cn/problems/n-repeated-element-in-size-2n-array/description/

int repeatedNTimes(vector<int>& nums) {
        unordered_map<int,int> countMap;
        for(auto e:nums)
            countMap[e]++;
        for(auto e:countMap)
            if(e.second==nums.size()/2)
                return e.first;
        return -1;
    }

. - 力扣(LeetCode). - 备战技术面试?力扣提供海量技术面试资源,帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。icon-default.png?t=O83Ahttps://leetcode.cn/problems/intersection-of-two-arrays/

vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> s1;
        for(auto e:nums1)
            s1.insert(e);
        unordered_set<int> s2;
        for(auto e:nums2)
            s2.insert(e);
        vector<int> vRet;
        for(auto e:s1)
            if(s2.find(e)!=s2.end())
                vRet.push_back(e);
        return vRet;
    }

 哈希函数

常见哈希函数

1. 直接定制法--(常用) 取关键字的某个线性函数为散列地址:Hash(Key)= A*Key + B 优点:简单、均匀 缺点:需要事先 知道关键字的分布情况 使用场景:适合查找比较小且连续的情况 面

2. 除留余数法--(常用) 设散列表中允许的地址数为m,取一个不大于m,但最接近或者等于m的质数p作为除数,按照哈希函 数:Hash(key) = key% p(p将关键码转换成哈希地 址

 哈希冲突

在往hash数组中存11时,就会发生hash冲突。

哈希冲突

对于两个数据元素的关键字 和 (i != j),有 != ,但有:Hash( ) == Hash( ),即:不同关键字通过 相同哈希哈数计算出相同的哈希地址,该种现象称为哈希冲突或哈希碰撞。

哈希冲突解决

闭散列

闭散列:也叫开放定址法,当发生哈希冲突时,如果哈希表未被装满,说明在哈希表中必然还有空位置,那 么可以把key存放到冲突位置中的“下一个” 空位置中去那如何寻找下一个空位置呢?

线性探测

线性探测:从发生冲突的位置开始,依次向后探测,直到寻找到下一个空位置为止。

插入

通过哈希函数获取待插入元素在哈希表中的位置

如果该位置中没有元素则直接插入新元素,如果该位置中有元素发生哈希冲突,使用线性探 测找到下一个空位置,插入新元素

二次探测

按2次方往后找空位置。

代码实现

enum State
{
	EMPTY,
	EXITS,
	DELETE,
};

template<class T>
struct HashData
{
	T _data;
	State _state;
};
template<class K,class T>
class HashTable
{

private:
	vector<HashData> _tables;
	size_t _num;//存储的有效数据的个数
};

三个转态对应查找时的三种情况

insert
负载因子

负载因子=表中数据/表的大小 -> 衡量哈希表满的程度
表接近满,插入数据容易冲突,冲突越多,效率越低

bool Insert(const T& x)
{
	KeyOfT koft;
	//计算x在表中的位置
	size_t index = koft(x) % _tables.size();
	while (_tables[index]._state == EXITS)
	{
		if (_tables[index]._data == x)
			return false;
		++index;
		if (index == _tables.size())
			index = 0;
	}
	_tables[index]._data = x;
	_tables[index]._state = EXITS;
	_num++;
}
find
HashData* Find(const K& key)
{
	KeyOfT koft;
	size_t index = key % _tables.size();
	while (_tables[index]._state != EMPTY)
	{
		if (koft(_tables[index]._data) == key)
		{
			if (_tables[index]._state == EXITS)
			{
				return &_tables[index];
			}
			else if (_tables[index]._state == DELETE)
			{
				return nullptr;
			}
		}
		++index;
		if (index == _tables.size())
		{
			index = 0;
		}
	}
	return nullptr;
}
erase
bool Erase(const K& key)
{
	HashData* ret = Find(key);
	if (ret)
	{
		ret->_state = DELETE;
		return true;
	}
	else
		return false;
}

标签:index,set,Hash,入门,tables,map,哈希,unordered
From: https://blog.csdn.net/2301_77479435/article/details/142386534

相关文章

  • 电气自动化入门05:三相异步电动机的正反转点动控制电路
    视频链接:3.2电工知识:三相异步电动机的正反转点动控制电路_1_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1PJ41117PW?p=6&vd_source=b5775c3a4ea16a5306db9c7c1c1486b51.断路器及其选型1.1断路器定义、分类、表示符号1.2.断路器功能、断路器脱钩方式1.3.电动......
  • 电气自动化入门04:三相交流异步电动机基础知识
    视频链接:3.1电工知识:三相交流异步电动机基础知识_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1PJ41117PW?p=5&vd_source=b5775c3a4ea16a5306db9c7c1c1486b5一、三相交流异步电动机基础知识11.三相交流异步电动机工作原理    是感应电动机的一种,是靠同时接......
  • 电气自动化入门03:安全用电
    视频链接:2.1电工知识:触电原因与防触电措施_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1PJ41117PW/?p=4&vd_source=b5775c3a4ea16a5306db9c7c1c1486b51.电流对人体的危害电击:电流通过人体。电伤:电流热效应、电弧烧伤、熔化金属溅出电磁场生理伤害:高频磁场影响人......
  • 【Redis入门到精通二】Redis核心数据类型(String,Hash)详解
    目录Redis数据类型1.String类型 (1)常见命令(2)内部编码2.Hash类型(1)常见命令(2)内部编码Redis数据类型    查阅Redis官方文档可知,Redis提供给用户的核心数据类型有以下九个,从上到下依次是字符串,哈希,列表,集合,有序集合,流,位图,位域,地址空间。因为Redis本身就是通......
  • 将阮一峰老师的《ES6入门教程》的源码拷贝本地运行和发布
    你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。阮一峰老师的《ES6入门教程》应该是很多同学学习ES6知识的重要参考吧,应该也有很多同学在看该文档的时候,想知道这个教程的前端源码是怎么实现的,也可能有同学下载了源码,发现运行起来不能正常切换,然后放弃了。今天分享下《ES6......
  • Nextjs 入门模板
    嗨,我为next.js创建了一个入门模板,它还包含typescript、tailwind、shadcn/ui。我已经在这里写过,但我添加了一些新功能,例如:Next-auth、Prisma、React-hook-form、T3-env。如果您喜欢这个项目,如果您留下一颗星星,我将不胜感激。?https://github.com/Skolaczk/next-starterNext.js......
  • STM32F407单片机编程入门(九)低功耗模式实战含源码
    文章目录一.概要二.STM32单片机低功耗基本介绍三.STM32F407单片机待机模式介绍四.CubeMX配置一个待机低功耗例程五.CubeMX工程源代码下载六.小结一.概要在生活中通过关掉电器组件可以实现省电节能的目的,同样的道理单片机也可以通过这种方法实现降低功耗。单片机是由......
  • AI产品经理到底有多吃香?零基础入门到精通,收藏这一篇就够了
    .markdown-bodypre,.markdown-bodypre>code.hljs{color:#333;background:#f8f8f8}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:700}.hljs-literal,.hljs-number,.hljs-tag.hljs-attr......
  • 模拟电路入门
    用电去控制电,这是计算机工作的核心原理。1、电流电流的单位:安培(A)。一秒内有6.2415093*10^8个元电荷,就是1A。单片机待机电流:10mA;鼠标和键盘的电流:20mA;强光手电筒:1A;笔记本电脑:3A;微波炉、烤箱、空调:10A;闪电:10000A。1.1、电路与电池电路就是电流导通的道路,电池是一种特殊......
  • three.js shader 入门 红旗飘动效果
    预览效果1、懒人直接上代码,全部代码效果import*asTHREEfrom"https://esm.sh/three";import{OrbitControls}from"https://esm.sh/three/examples/jsm/controls/OrbitControls";consttextureLoader=newTHREE.TextureLoader()letcontrols;letscene:TH......