STL: unordered_map 自定义键值类型的使用

当试图使用自定义类型作为 unordered_map 的键值时,则必须为自定义类型定义 Hash 函数与相等的判断条件。我们先定义自定义类型作键值,代码如下:

struct KEY
{
    int first;
    int second;
    int third;
 
    KEY(int f, int s, int t) : first(f), second(s), third(t){}
};
    1. Hash 函数
    必须为 override 了 operator() 的一个类,一般自定义类型可能包含几种内置类型,我们可以分别计算出内置类型的 Hash Value 然后对它们进行 Combine 得到一个哈希值,一般直接采用移位加异或(XOR)便可得到还不错的哈希值(碰撞不会太频繁),如下:

struct HashFunc
{
    std::size_t operator()(const KEY &key) const 
    {
        using std::size_t;
        using std::hash;
 
        return ((hash<int>()(key.first)
            ^ (hash<int>()(key.second) << 1)) >> 1)
            ^ (hash<int>()(key.third) << 1);
    }
};


    另外一种方法是直接实例化模板,这样的话使用 unordered_map 时便不用再指定 Hash 函数,但要求必须为 KEY 重载 operator ==,实例化模板如下:


namespace std 
{
    template <>
    struct hash<KEY>
    {
        std::size_t operator()(const KEY &key) const
        {
            using std::size_t;
            using std::hash;
 
            // Compute individual hash values for first,
            // second and third and combine them using XOR
            // and bit shifting:
 
            return ((hash<int>()(key.first)
                ^ (hash<int>()(key.second) << 1)) >> 1)
                ^ (hash<int>()(key.third) << 1);
        }
    };
}

    2. 相等函数
    哈希需要处理碰撞,意味着必须得知道两个自定义类型对象是否相等,所以必须得提供比较相等的方法,可以 overload operator ==,可以用 std::equal,也可以实现一个 override operator () 的类,这里我们采用后者(这也意味着 Hash 函数不能使用实例化模板的方法,只能定义一个重载了 operator() 的类),代码如下:

struct EqualKey
{
    bool operator () (const KEY &lhs, const KEY &rhs) const
    {
        return lhs.first  == rhs.first
            && lhs.second == rhs.second
            && lhs.third  == rhs.third;
    }
};

    3. 应用实例
    下面为一个具体应用的例子

int main()
{
    unordered_map<KEY, string, HashFunc, EqualKey> hashmap =
    {
        { { 01, 02, 03 }, "one" },
        { { 11, 12, 13 }, "two" },
        { { 21, 22, 23 }, "three" },
    };
 
    KEY key(11, 12, 13);
 
    auto it = hashmap.find(key);
    
     if (it != hashmap.end())
     {
         cout << it->second << endl;
     }
 
    return 0;
}

 

转自:https://blog.csdn.net/zhangpiu/article/details/49837387

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
### 回答1: std::unordered_map是C++ STL中的一个关联容器,用于存储对。它使用哈希表实现,可以快速地查找和插入元素。使用时需要包含头文件<unordered_map>。 使用std::unordered_map时,需要定义类型,并可以选择自定义哈希函数和比较函数。可以使用insert()函数插入元素,使用find()函数查找元素,使用erase()函数删除元素。还可以使用迭代器遍历容器中的元素。 需要注意的是,std::unordered_map中的元素是无序的,插入和查找的时间复杂度为O(1)。但是,由于哈希表的实现,插入和查找的速度可能会受到哈希冲突的影响。因此,在使用std::unordered_map时,需要根据具体情况选择合适的哈希函数和负载因子,以提高容器的效率。 ### 回答2: std::unordered_map是C++ STL中的一个哈希表容器,用来存储对。它类似于std::map,但是它的对没有从小到大排序,而是通过哈希函数计算从而快速查找。因此,std::unordered_map的效率比std::map高,但是它的迭代器不保证顺序。 std::unordered_map可以存储任何可哈希化的类型作为对可以通过insert或emplace函数添加到unordered_map中。 unordered_map的查找可以使用find函数,如果存在则返回一个指向该的迭代器,否则返回end()。其他的 STL 操作,例如erase,size,empty等也可以应用到std::unordered_map中。 std::unordered_map通过哈希函数来计算每个的索引,哈希函数映射可以通过unordered_map的模板参数进行定义。如果你没有指定自定义哈希函数,则std :: hash将用于大多数内置类型。如果你需要使用定义类型作为,你可以重载 std::hash和==运算符,或者使用std::hash自定义模板的计算哈希函数。在使用定义类型作为时,保证哈希函数的返回与==运算符的判断方法一致。 实际上,std::unordered_map的内部实现也是使用了哈希表,当不同的通过哈希函数计算到同一个索引位置时,就会出现哈希碰撞,std::unordered_map使用链表来解决碰撞。当链表中的节点超出一定阈时,哈希表会扩容,以提高效率。 总之,std::unordered_map是一个高性能的 STL 容器,可以用来存储不需要排序的对,并可以快速查找。它也是一个非常适合处理大量数据的容器,但由于哈希冲突的存在,其效率与容量的关系是具有一定的影响的。在使用时需要注意哈希函数的选择及哈希碰撞的处理。 ### 回答3: std::unordered_map是C++ STL中的一个关联容器,用于存储对,它的特点在于插入、删除和查找元素的时间复杂度都是O(1),效率较高。在使用std::unordered_map之前,需要包含头文件#include<unordered_map>。 std::unordered_map的基本用法如下: 1.创建unordered_map对象 std::unordered_map<int, std::string> map; 2.插入元素 map.insert(std::make_pair(1, "apple")); 3.访问元素 std::string value = map[1]; 4.删除元素 map.erase(1); 5.判断是否存在某个 if(map.find(1) == map.end()) { //不存在 } else { //存在 } 6.遍历unordered_map for(auto iter = map.begin(); iter != map.end(); ++iter) { std::cout << iter->first << ":" << iter->second << std::endl; } std::unordered_map还有许多其他的用法,例如使用emplace函数插入元素、使用at函数访问元素、使用bucket_count函数获取桶的数量等等。需要根据具体情况,灵活运用。 总之,std::unordered_map是C++ STL中一个非常实用的关联容器,具有高效、快速、方便等优点,可以满足许多实际开发需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值