C++ STL unordered_map

map hashmap

文章目录

unordered_map 中每一个元素都是一个 key-value 对,数据类型为 pair
std::pair 主要的作用是将两个数据组合成一个数据,两个数据可以是同一类型或者不同类型。
pair 实质上是一个结构体,其主要的两个成员变量是 first 和 second ,这两个变量可以直接使用。

初始化一个 pair 可以使用构造函数,也可以使用 std::make_pair 函数,make_pair 函数的定义如下:
template pair make_pair(T1 a, T2 b) { return pair(a, b); }

一般 make_pair 都使用在需要 pair 做参数的位置,可以直接调用 make_pair 生成 pair 对象。

c 复制代码
pair<string, int> student ("zhangsan", 17);  // name-age
student.first = "zhangsan"; 
student.second = 17; 

product3 = make_pair ("shoes",20.0);

Map、HashMap概念

  • Map 是 STL 的一个关联容器,以键值对存储的数据,其类型可以自己定义,每个关键字在 map 中只能出现一次,关键字不能修改。map 也可以说关于 key-value 的映射。
  • HashMap 是基于哈希表实现的,每一个元素是一个 key-value 对。以空间换时间,是存储 key-value 键值对的集合。

map、hashmap 的区别

  • hash_map 底层采用 hash 表存储,map 一般采用红黑树实现,所以 hash_map 的 key 值是无序的,map 存储是有有序的。
  • map 的优点在于可以自动按照 Key 值进行排序,查找时间复杂度是log(n) ;hash_map 优点在于它各项操作的平均时间复杂度接近常数,即O(1).

引用头文件

c 复制代码
#include <unordered_map>

初始化赋值

c 复制代码
unordered_map<string,string> name_Address =
    {
        {"张三","beijing"},
        {"李四","shanghai"},
        {"王五","shenzhen"},
    };

unordered_map 自定义键值类型

如果要将自定义类型作为unordered_map的键值,需如下两个步骤:

  1. 定义哈希函数的函数对象;
  2. 定义等比函数的函数对象或者在自定义类里重载operator==()

注意:

  1. 重载运算符时必须加上 const
  2. 定义哈希函数的函数对象时,返回值必须为 int
  3. 打印键值的数据时根据自定义数据类型打印
  4. 自定义数据类型 默认的缺省构造函数 不能省略,否则会出现编译错误:没有合适的默认构造函数可用。

参考:https://blog.csdn.net/qq_43450920/article/details/127078664

c 复制代码
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

struct student{
    student(string str, int a) : name(str), age(a) {};
    bool operator==(const student& stu2) const {
        return stu2.name == name && stu2.age == age;
    }
    string name;
    int age;
};

// 定义哈希函数的函数对象
template<class T>
struct Hash {
    size_t operator()(const T& key) const{
        return key.age;
    }
};

// 定义等比函数的函数对象
template<class T>
struct MyEqual {
    bool operator()(const T& key1, const T& key2) const {
        return key1.name == key2.name && key1.age == key2.age;
    }
};

int main() {
    struct student stu1 = {"zhangsan", 17};
    unordered_map<student, string, Hash<student>> students = {make_pair(stu1, "13班")};
    for(auto x : students) {
        cout<< x.first.name << " " << x.first.age << "岁 " << x.second << endl;
    }
	return 0;
}

unordered_map 的 value 自定义数据类型

unordered_map 的 value 自定义数据类型时,无特殊操作,按照常见数据类型操作即可

c 复制代码
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

struct student{
    string name;
    int age;
};

int main() {
    struct student stu1 = {"zhangsan", 17};
    unordered_map<string, student > students = {make_pair("13班", stu1)};
    for(auto x : students) {
        cout<< x.first << " " << x.second.name << " " << x.second.age << "岁 "  << endl;
    }

	return 0;
}

遍历

  1. 迭代器遍历
c 复制代码
for ( auto it = name_Address.begin(); it != name_Address.end(); ++it )
        cout << " " << it->first << ":" << it->second;
  1. range for循环遍历
c 复制代码
for ( auto x : name_Address )
        cout << " " << x.first << ":" << x.second;

常用方法

插入

  1. 构造时插入 pari 类型
c 复制代码
pair<string, int> student ("zhangsan", 17);
student.insert (student1); 
student.insert (make_pair<string, int>("lisi", 18)); 
  1. 构造时插入 数组 类型
c 复制代码
// 初始化数组插入(可以用二维一次插入多个元素,也可以用一维插入一个元素)
student.insert ({{"zhangsan", 17}, {"lisi", 18}});
  1. 数组形式插入
c 复制代码
//数组形式插入
myrecipe["coffee"] = 10.0;

查找 key

c 复制代码
unordered_map<string, int>::iterator get = student.find ("zhangsan");

if ( get == student.end() )
    cout << "not found";
else
    cout << "found "<<get->first << " is " << get->second<<"\n\n";

修改 value

c 复制代码
student.at("zhangsan") = 18;
student["zhangsan"] = 17;

删除元素

c 复制代码
// 1. 通过位置
student.erase(myrecipe.begin());

// 2. 通过key
student.erase("milk");

清空元素

c 复制代码
student.clear();
相关推荐
CVer儿5 分钟前
起源引擎harmmer++ 配置
开发语言
星夜离尘569 分钟前
MATLAB FFT 单边幅度谱:归一化、奇偶长度与频谱泄漏的完整实验
开发语言·matlab·信号处理·频谱分析·fft
fpcc10 分钟前
c++20新功能—std::osyncstream
c++·c++20
H.莓飛10 分钟前
【C++】模板初阶
linux·开发语言·c++·visual studio
十五年专注C++开发12 分钟前
基于Asio2实现http服务器的实践总结(二)
服务器·c++·http·asio2
Wang's Blog15 分钟前
Java 项目实战: 交友项目 - 项目模块划分与依赖关系
java·开发语言·交友
技术不好的崎鸣同学16 分钟前
第七章:模块踩踏以覆写导出函数绕过CFG
c++·windows·安全·系统安全
努力进修16 分钟前
时序数据长期承载难题:从压缩、批量写入到数据组织优化
java·开发语言·数据库
miofly16 分钟前
GitHub 今日推荐|ps2-web-recomp:浏览器里跑 PS2 游戏的静态重编译方案
c++·开源·github
星夜离尘5616 分钟前
MATLAB 5 点滑动平均:filter 与 conv 的输出对齐,以及 2 样本延时的含义
开发语言·算法·matlab·滤波·fir