unordered_map

本文对比了C++ STL中的unordered_map与map的数据结构特点及使用场景。unordered_map通过哈希函数定位,适用于不需排序的情况,提高了查找效率;而map则保持元素有序,适合需要排序的场景。文中还详细介绍了如何自定义哈希函数和等价比较函数。

学习数据结构的时候 偶然得知有个unordered_map,以前没有用过,查了查相关内容,据说效率比map高出很多,而且耗资源也少,研究一下

至于具体效率咋样我就不去验证了,网上太多了

参考:http://blog.youkuaiyun.com/whizchen/article/details/9286557

关键是

unordered_map与map的区别

boost::unordered_map, 它与 stl::map的区别就是,stl::map是按照operator<比较判断元素是否相同,以及比较元素的大小,然后选择合适的位置插入到树中。所以,如果对map进行遍历(中序遍历)的话,输出的结果是有序的。顺序就是按照operator< 定义的大小排序。
而boost::unordered_map是计算元素的Hash值,根据Hash值判断元素是否相同。所以,对unordered_map进行遍历,结果是无序的。
用法的区别就是,stl::map 的key需要定义operator< 。 而boost::unordered_map需要定义hash_value函数并且重载operator==。对于内置类型,如string,这些都不用操心。对于自定义的类型做key,就需要自己重载operator== 或者hash_value()了。 
最后,说,当不需要结果排好序时,最好用unordered_map。


linux下使用

普通的key就不说了和map一样

看一下用sockaddr_in 作为key的方法

<span style="font-family:Microsoft YaHei;font-size:18px;">#ifndef CSESSION_H  
#define CSESSION_H  
  
#include <netinet/in.h>  
#include <time.h>  
#include <map>  
#include <string.h>  
#include <tr1/unordered_map>  //头文件  
#include <iostream>  
  
using namespace std;  
using namespace std::tr1;  
  
struct Terminal  
{  
    int             nid ; //id  the key for terminal  
    sockaddr_in     addr; //ip  the key for Client  
    time_t          tm;   //last alive time  
    enTerminalStat  enStat;//status  
    Terminal();  
    ~Terminal();  
    Terminal &operator =(const Terminal& term);  
};  
  
  
struct hash_func  //hash 函数  
{  
    size_t operator()(const sockaddr_in &addr) const  
    {  
         return addr.sin_port*9999 + addr.sin_addr.s_addr;  
    }  
};  
struct cmp_fun //比较函数 ==  
{  
    bool operator()(const sockaddr_in &addr1, const sockaddr_in &addr2) const  
    {  
         return memcmp(&addr1, &addr2, sizeof(sockaddr_in)) == 0 ? true:false;  
    }  
};  
  
//typedef unordered_map<int,Terminal*> MapTerminal; // Terminal socket 作为key  
//typedef unordered_map<int,Terminal*>::iterator MapTerminal_It; //  
  
typedef unordered_map<sockaddr_in, Terminal*,hash_func, cmp_fun> MapClientSession; // sockaddr_in作为key  
typedef unordered_map<sockaddr_in, Terminal*,hash_func, cmp_fun>::iterator MapClientSession_It; //  
  
  
#endif // CSESSION_H</span>  

operator== 有两种方式

一种是

struct st

{

 bool operator==(const st &s) const

...

};

另一种就是自定义函数体,代码中

struct cmp_fun

{

bool operator()(...)

...

}


必须要自定义operator==和hash_value。 重载operator==是因为,如果两个元素的hash_value的值相同,并不能断定这两个元素就相同,必须再调用operator==。 当然,如果hash_value的值不同,就不需要调用operator==了。


文章转载自:http://blog.youkuaiyun.com/liuhongxiangm/article/details/17395831

### C++ `unordered_map` 的基本概念 `unordered_map` 是一种基于哈希表的数据结构,在标准模板库 (STL) 中提供。它允许通过键快速访问关联的值,平均时间复杂度为 O(1)[^1]。 #### 基本语法 以下是创建和初始化 `unordered_map` 的方法: ```cpp #include <unordered_map> #include <string> std::unordered_map<std::string, int> myMap; myMap["apple"] = 5; // 插入或更新键值对 int value = myMap["banana"]; // 如果不存在,则会自动插入默认值0并返回该值 ``` 上述代码展示了如何定义一个字符串到整数类型的映射,并演示了插入操作以及查找操作的行为[^2]。 #### 主要成员函数 | 函数名 | 功能描述 | |----------------|--------------------------------------------------------------------------| | insert(key,val)| 向容器中插入新的键值对 | | find(key) | 查找指定 key 对应的迭代器;如果找不到则返回 end() | | count(key) | 返回找到的具有特定 key 的元素数量 | | erase(key) | 删除指定 key 的元素 | 这些功能使得管理大量数据变得高效而简单[^3]。 ### 性能考量 虽然理论上讲,`unordered_map` 提供常量级的时间复杂度用于大多数操作,但在实际应用中有几个因素会影响其表现: - **负载因子**: 负载因子是指当前存储条目数目除以桶的数量。当这个比率过高时可能导致更多的冲突从而降低效率。可以通过调整最大负载因子来优化性能。 - **哈希碰撞处理机制**: 当两个不同的键被分配到了同一个位置上就会发生碰撞。解决这些问题通常采用链地址法或者开放寻址技术。前者更常见于 STL 实现之中[^4]。 - **重新散列(rehashing)**: 随着新项目不断加入集合当中,为了维持较低水平的负荷系数,有必要周期性地增加内部数组大小并对所有现有记录重新计算它们的位置。这一过程可能耗费较多资源所以应该谨慎对待频繁变动规模较大的场景下的使用情况[^5]。 ```cpp // 设置自定义的最大装载因子 myMap.max_load_factor(0.75); // 手动触发重哈希至至少容纳 n 个元素所需的容量 myMap.rehash(n); ``` 以上片段说明了如何手动控制一些影响性能的关键参数设置方式[^6]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值