C++ STL unordered_map 与 unordered_set 使用详解

【C++】STL详解(十一)—— unordered_set、unordered_map的介绍及使用 今天我们比较详细地完成了 unordered_set、unordered_map的介绍及使用,了解了一些有关的底层原理。接下来,我们用哈希表封装出unordered_map和unordered_set。希望我的文章和讲解能对大家的学习提供一些帮助。 阅读详情

目录


前言

写一个单词频率统计程序,你用 map<string, int>,运行后发现比同事的 Python dict 慢了一截。一查资料才发现——map 底层是红黑树,查找 O(log n);而 Python 的 dict 是哈希表,查找 O(1)。

C++ 有没有哈希表版本的 map?当然有,它就是本文的主角——unordered_map。

C++11 引入了四大无序关联容器:unordered_map、unordered_set、unordered_multimap、unordered_multiset。本文聚焦最常用的前两个,从使用技巧讲到避坑指南,带你彻底玩转它们。


一、先搞清楚——有序 vs 无序

在学 unordered_map 之前,先搞明白它和 map 的本质区别:

map / setunordered_map / unordered_set
底层结构红黑树(平衡二叉搜索树)哈希表(链地址法)
元素顺序按 key 自动排序无序(按哈希值分布)
查找复杂度O(log n)平均 O(1),最坏 O(n)
插入复杂度O(log n)平均 O(1),最坏 O(n)
内存占用较小较大(需要维护桶数组 + 链表)
适用场景需要有序遍历需要快速增删查,不关心顺序

一句话总结:要排序用 map,要速度用 unordered_map。


二、unordered_map 核心 API 速查

2.1 头文件与构造

#include <unordered_map>
#include <string>
using namespace std;

// 默认构造
unordered_map<string, int> umap1;

// 初始列表构造
unordered_map<string, int> umap2 = {
    {"apple",  3},
    {"banana", 5},
    {"cherry", 2}
};

// 拷贝构造
unordered_map<string, int> umap3(umap2);

// 指定初始桶大小
unordered_map<string, int> umap4(64);  // 预分配64个桶,减少rehash

2.2 插入元素

unordered_map<string, int> umap;

// 方式1:insert + pair
umap.insert(pair<string, int>("apple", 3));

// 方式2:insert + make_pair
umap.insert(make_pair("banana", 5));

// 方式3:insert + 初始化列表(最简洁)
umap.insert({"cherry", 2});

// 方式4:operator[] —— 最常用!
umap["durian"] = 8;       // 不存在则插入,存在则修改
umap["apple"] = 10;       // apple已存在,将值从3改为10

// 方式5:emplace —— 原地构造,效率最高
umap.emplace("elderberry", 4);

insert vs operator[] vs emplace:

方法key已存在时key不存在时返回值
insert插入失败插入成功pair<iterator, bool>
operator[]覆盖旧值插入(value默认构造,再赋值)mapped_type&
emplace插入失败原地构造插入pair<iterator, bool>

注意:operator[] 在 key 不存在时会先用默认构造函数创建一个 value,再赋值。如果 value 类型没有默认构造函数,编译报错。此时必须用 insert 或 emplace。

2.3 查找元素

unordered_map<string, int> umap = {{"apple", 3}, {"banana", 5}};

// 方式1:find —— 最常用
auto it = umap.find("apple");
if (it != umap.end())
{
    cout << "找到了: " << it->second << endl;
}

// 方式2:count —— 判断key是否存在(返回0或1)
if (umap.count("banana"))
{
    cout << "banana 存在" << endl;
}

// 方式3:contains (C++20) —— 语义更清晰
if (umap.contains("cherry"))   // C++20
{
    cout << "cherry 存在" << endl;
}

// 方式4:operator[] + 判断(有副作用!)
// 不推荐用于查找,因为key不存在时会偷偷插入!
// int val = umap["durian"];  // durian 被悄悄插入了!

find vs count 怎么选:只需判断存在用 count(或 C++20 的 contains);需要访问 value 用 find。

2.4 删除元素

unordered_map<string, int> umap = {{"a", 1}, {"b", 2}, {"c", 3}};

// 按 key 删除 —— 返回删除的元素个数(0 或 1)
size_t n = umap.erase("a");           // n = 1
size_t m = umap.erase("nonexist");    // m = 0

// 按迭代器删除 —— 返回被删元素的下一个迭代器
auto it = umap.find("b");
if (it != umap.end())
{
    auto next = umap.erase(it);       // next 指向 "c"
}

// 清空
umap.clear();

2.5 遍历

unordered_map<string, int> umap = {{"a", 1}, {"b", 2}, {"c", 3}};

// 方式1:迭代器遍历
for (auto it = umap.begin(); it != umap.end(); ++it)
{
    cout << it->first << " : " << it->second << endl;
}

// 方式2:范围for(C++11,推荐)
for (const auto& kv : umap)
{
    cout << kv.first << " : " << kv.second << endl;
}

// 方式3:结构化绑定(C++17)
for (const auto& [key, value] : umap)
{
    cout << key << " : " << value << endl;
}

重要:遍历顺序是无序的,不一定等于插入顺序,每次运行可能不同。

2.6 容量与桶信息

unordered_map<string, int> umap;

umap.empty();        // 是否为空
umap.size();         // 元素个数
umap.max_size();     // 理论上能容纳的最大元素数

// 桶相关 —— 调试和性能调优时用
umap.bucket_count();      // 桶的数量
umap.max_bucket_count();  // 最大桶数
umap.bucket("apple");     // 查询 "apple" 在哪个桶
umap.bucket_size(0);      // 第0号桶中有几个元素

// 负载因子
umap.load_factor();       // 当前负载因子 = size / bucket_count
umap.max_load_factor();   // 最大负载因子(默认1.0)
umap.max_load_factor(0.7); // 设置最大负载因子为0.7

三、unordered_set 核心 API 速查

unordered_set 的 API 与 unordered_map 高度一致,区别只在于只存 key,没有 value。

3.1 基本操作

#include <unordered_set>

unordered_set<int> uset = {1, 2, 3, 4, 5};

// 插入
uset.insert(6);
uset.emplace(7);

// 查找
auto it = uset.find(3);
if (uset.count(4))  { /* 存在 */ }

// 删除
uset.erase(1);          // 按值删除
uset.erase(uset.begin()); // 按迭代器删除

// 遍历
for (const auto& val : uset)
{
    cout << val << " ";
}

3.2 去重神器

unordered_set 天然去重,常用于批量去重场景:

vector<int> nums = {1, 2, 2, 3, 3, 3, 4, 5, 5};
unordered_set<int> uset(nums.begin(), nums.end());

// uset 中只剩 {1, 2, 3, 4, 5},顺序不确定
vector<int> unique_nums(uset.begin(), uset.end());

四、自定义哈希函数——我的 key 我做主

4.1 问题场景

// 这行代码能编译吗?
unordered_map<pair<int, int>, string> umap;  // ❌ 编译错误!

为什么报错?因为 C++ 标准库没有为 pair<int, int> 提供默认的哈希函数。你需要自己写一个。

4.2 三种自定义方式

方式一:仿函数(推荐)

struct PairHash
{
    size_t operator()(const pair<int, int>& p) const
    {
        size_t h1 = hash<int>()(p.first);
        size_t h2 = hash<int>()(p.second);
        // 经典组合哈希:h = h1 * 质数 + h2
        return h1 * 131 + h2;
    }
};

unordered_map<pair<int, int>, string, PairHash> umap;
umap[{1, 2}] = "hello";  // 可以正常编译运行了

方式二:特化 std::hash(不推荐侵入标准命名空间)

namespace std
{
    template<>
    struct hash<pair<int, int>>
    {
        size_t operator()(const pair<int, int>& p) const
        {
            return hash<int>()(p.first) * 131 + hash<int>()(p.second);
        }
    };
}

方式三:Lambda(C++20)

auto hash_func = [](const pair<int, int>& p) -> size_t {
    return p.first * 131 + p.second;
};
// 注意:unordered_map 的 Hash 模板参数需要可默认构造的类型,lambda不行
// 除非使用 decltype,但比较繁琐,推荐方式一

4.3 自定义等值比较

如果你的 key 需要自定义比较规则(不只是用 ==),可以传入第四个模板参数:

struct CaseInsensitiveEqual
{
    bool operator()(const string& a, const string& b) const
    {
        // 忽略大小写比较
        if (a.size() != b.size()) return false;
        for (size_t i = 0; i < a.size(); ++i)
        {
            if (tolower(a[i]) != tolower(b[i])) return false;
        }
        return true;
    }
};

struct CaseInsensitiveHash
{
    size_t operator()(const string& s) const
    {
        string lower;
        for (char c : s) lower += tolower(c);
        return hash<string>()(lower);
    }
};

// 四个模板参数:Key, Value, Hash, KeyEqual
unordered_map<string, int, CaseInsensitiveHash, CaseInsensitiveEqual> umap;

五、实战案例

5.1 单词频率统计(经典面试题)

#include <iostream>
#include <unordered_map>
#include <vector>
#include <sstream>
using namespace std;

unordered_map<string, int> wordCount(const string& text)
{
    unordered_map<string, int> freq;
    istringstream iss(text);
    string word;

    while (iss >> word)
    {
        ++freq[word];  // operator[]:不存在则自动插入并初始化为0
    }
    return freq;
}

int main()
{
    string text = "apple banana apple cherry banana apple";
    auto result = wordCount(text);

    for (const auto& [word, count] : result)
    {
        cout << word << ": " << count << endl;
    }
    return 0;
}

5.2 两数之和(LeetCode 1)

vector<int> twoSum(vector<int>& nums, int target)
{
    unordered_map<int, int> indexMap;  // 值 -> 下标

    for (int i = 0; i < nums.size(); ++i)
    {
        int complement = target - nums[i];
        auto it = indexMap.find(complement);
        if (it != indexMap.end())
        {
            return {it->second, i};
        }
        indexMap[nums[i]] = i;
    }
    return {};
}

时间复杂度 O(n),如果用 map 是 O(n log n)。这 10 倍的差距就是 unordered_map 存在的意义。

5.3 用 unordered_set 实现交集 / 并集

vector<int> intersection(const vector<int>& a, const vector<int>& b)
{
    unordered_set<int> set_a(a.begin(), a.end());
    vector<int> result;

    for (int num : b)
    {
        if (set_a.count(num))       // b中的元素在a中存在
        {
            result.push_back(num);
            set_a.erase(num);       // 去重:每个交集元素只出现一次
        }
    }
    return result;
}

vector<int> union_set(const vector<int>& a, const vector<int>& b)
{
    unordered_set<int> result(a.begin(), a.end());
    result.insert(b.begin(), b.end());
    return vector<int>(result.begin(), result.end());
}

5.4 预分配桶大小——避免重复 rehash

当你大概知道要插入多少元素时,提前分配桶可以显著提升性能:

unordered_map<int, string> umap;
umap.reserve(100000);  // 预分配足够的桶,避免多次 rehash

for (int i = 0; i < 100000; ++i)
{
    umap.emplace(i, "value");  // 全程不会触发 rehash
}

reserve(n) 会调整 bucket_count 使得至少可以容纳 n 个元素而不触发 rehash。而 rehash(n) 直接将桶数设为至少为 n。


六、常见踩坑与避坑指南

坑1:遍历时修改容器

// ❌ 错误:遍历中删除会导致迭代器失效
for (const auto& kv : umap)
{
    if (kv.second == 0)
    {
        umap.erase(kv.first);  // 迭代器失效,程序崩溃
    }
}

// ✅ 正确:C++20 erase_if 或手动处理
for (auto it = umap.begin(); it != umap.end(); )
{
    if (it->second == 0)
    {
        it = umap.erase(it);  // erase 返回下一个有效迭代器
    }
    else
    {
        ++it;
    }
}

坑2:用 operator[] 查找导致意外插入

void printIfExists(unordered_map<string, int>& umap, const string& key)
{
    // ❌ 错误:umap[key] 在 key 不存在时会偷偷插入!
    // cout << umap[key] << endl;

    // ✅ 正确:用 find
    auto it = umap.find(key);
    if (it != umap.end())
    {
        cout << it->second << endl;
    }
}

坑3:pair 做 key 忘记写哈希函数

// ❌ 编译错误
unordered_map<pair<int, int>, string> umap;

// ✅ 自定义哈希
struct PairHash { /* ... */ };
unordered_map<pair<int, int>, string, PairHash> umap;

坑4:浮点数做 key

unordered_map<double, string> umap;  // 危险!

浮点数的 == 比较和哈希值计算都受精度影响,0.1 + 0.2 和 0.3 可能哈希到不同的桶。尽量不要用浮点数做 key。


七、性能对比实测

用一个简单的 benchmark 感受一下差距:

#include <chrono>
// 100万个随机插入 + 查找
容器插入 100万 元素查找 100万 次有序遍历
map~780ms~650msO(n),天然有序
unordered_map~420ms~280ms不支持

数据仅供参考,实际性能与 key 类型的哈希开销、负载因子设置、是否触发 rehash 等因素相关。

如果你的场景需要频繁地增删查且不关心顺序,选 unordered_map 就对了。如果需要按 key 排序输出,map 是不二之选。


八、总结

本文覆盖了 unordered_map 和 unordered_set 从入门到进阶的核心知识点:

知识点要点
底层结构哈希表,平均 O(1) 增删查
常用 APIinsert / emplace / find / count / erase / operator[]
遍历范围 for / 迭代器,遍历顺序无序
自定义哈希传入函数对象作为第三个模板参数
自定义比较传入函数对象作为第四个模板参数
性能调优reserve 预分配、max_load_factor 控制负载因子
常见坑operator[] 的副作用、遍历删除、对组做 key 缺哈希函数

理解原理 ,掌握 API,知道常见的坑在哪里,就算是真正玩转了 C++ 的哈希容器。


本文是个人学习笔记,如有疏漏,欢迎评论区指正讨论。

STL-unordered_set和unordered_map的基本使用 unordered_set和unordered_map的基本使用unordered_setunordered_set的使用unordered_set的定义方式unordered_set的常用接口unordered_multisetunordered_mapunordered_map的定义方式unordered_map的主要接口使用unordered_multimap ????快速导航关联在一起的文章???? 文章名称 链接 二叉搜索树 点击直达文章 set和map的基本使用 点击直达文章 阅读详情

相关推荐

C++语言基础:STL----unordered_map、unordered_multimap、unordered_set、unordered_multiset

2.9、unordered_map 2.9.1、unordered_map基本概念 1、简介 1. unordered_map是无序 map 容器, C++11标准,底层是哈希表存储结构;解决冲突:链地址法 2. pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值) 3. 所有元素都根据元素的键值无序排序 2、本质:map与unordered_map的区别 1). map是关联式容器,unordered_map是无序容器 2).

changlif的博客 704

【C++初阶】STL详解(十二)—— unordered_set、unordered_map的介绍及使用

【C++初阶】STL详解(十二)—— unordered_set、unordered_map的介绍及使用

小小unicorn的博客 1531

STL详解(十二)—— unordered_set、unordered_map的介绍及使用

文章目录unordered_set和unordered_map的介绍unordered_set的使用unordered_set的定义方式unordered_set接口的使用unordered_multisetunordered_map的使用unordered_map的定义方式unordered_map接口的使用unordered_multimap unordered_set和unordered_map的介绍 unordered_set的使用 unordered_set的定义方式 方式一: 构造一个某类型的空

2021dragon的博客 1万+

C++第三十九弹---C++ STL中的无序容器:unordered_set与unordered_map使用详解

unordered_set/unordered_map的构造,容量,迭代器,查询,修改操作,桶操作,unordered_map的元素访问

小林熬夜学习编程的博客 2194

【 C++ 】unordered_map和unordered_set的介绍和使用

目录 1、unordered系列关联式容器 2、unordered_map unordered_map的介绍 unordered_map的构造方式 unordered_map的函数接口说明 unordered_multimap 3、unordered_set unordered_set的介绍 unordered_set的构造方式 unordered_set的函数接口说明

bit_zyx的博客 7700

基于紫光同创FPGA的adf网表文件使用和黑匣子设置

这个时候就可以选择将你的网表文件给到他使用,就是相当于把你的功能模块封装成了一个黑匣子一样,只有外部端口,没有内部代码;,在TOP层的子模块声明里面需要加上/*synthesis syn_black_box */进行黑匣子设置,此时子层 adf 文件作为黑盒是不会综合的,在 device map 时会将顶层综合结果与子层 adf 文件合并传递至布局布线阶段;这些都设置完毕后呢,就可以对工程进行编译和综合了,综合完毕后会生成一个.adf的网表文件,我们要使用的就是这个文件;我这里是把两个子模块的添加了哈;

H2061722的博客 963

C++STL详解(十) -- 使用哈希表封装unordered_set和unordered_map

(1):set模板参数要求能够支持小于比较,例如:二叉搜索树查找成员函数中,我们可以利用compare仿函数将当前结点值与所给值比较,从而决定cur遍历左子树还是右子树,为了能够支持大于比较的,我们可以交换一下实参位置,这也间接支持了大于比较.并且条件判断,进而也支持了等于.(1)针对于K类型(指针,打浮点数,有符号整型)可以转换为无符号整数取模.对于string,日期类类型,这两个类型与整型类型无关的,此时不可以直接强转为整数,需要相应的提供将该类型转换为整数的仿函数.

清欢Allen的技术博客 1151

ISP——坏点矫正(Defective Pixel Correction,DPC)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录一、出现原因二、坏点分类三、矫正方法动态矫正1.PINTO算法2.梯度法3.DPC和demosaic结合法4.行检测法 一、出现原因 1.感光元件芯片自身工艺技术瑕疵造成以及长期使用造成的瑕疵; 2.光线采集存在缺陷; 二、坏点分类 1.hot pixel: 固定保持较高的像素值,一般呈现为画面高亮的点; 2.dead pixel: 固定保持较低的像素值,一般在画面中呈现为暗点; 3.noise pixel:信号强度随光照呈现的.

qq_41939460的博客 9421

C++ STL 库函数使用自查

本文摘要: C++容器分为顺序容器、关联容器和容器适配器三大类。顺序容器(如vector、deque、list等)直接存储数据,支持完整接口;容器适配器(如stack、queue、priority_queue)则基于顺序容器实现特定功能接口。 重点介绍了双端队列deque的特性:支持O(1)时间复杂度的头尾插入删除操作,采用分段连续内存结构,相比vector在头部操作和扩容方面更有优势。详细列出了deque的常用方法和初始化方式,并与vector进行了对比。 对于容器适配器,主要讲解了queue(先进先出队

weixin_43744293的博客 189

ESP32 LVGL开发板例程使用记录:自制常用汉字字库(二)

1、将下载的文件移入工程文件中 ,路径为项目文件中 ”......\lib\lvgl\src\font“文件夹下。3、修改字库配置文件,文件名为lv_conf.h中的内容,向其中加入下面内容(位置可搜索注释块来找到地方)修改完成可以编译试试,看是否成功,如字库较大时编译出错,请使能:LV_FONT_FMT_TXT_LARGE。2、打开此文件,修改包含头文件的路径,不然会报错,修改方法可对照自己库中其他字库文件中的包含路径。导入完成后在VSCode工程中可以查看到此文件。上次说完了如何制作 字库.c 文件。

qq_43279097的博客 1954

在x86机器上运行jailhouse

jailhouse jaihouse提供了一个demo ,https://github.com/siemens/jailhouse-images可以用于编译一整套可用的demo。 适用于多个平台。编译过程主要参考https://blog.youkuaiyun.com/weixin_39541632/article/details/110422345 此demo可以生成多个平台所用的操作系统image。 ...

闲人的专栏 3004

C++ STL学习笔记

淘汰需要老老实实些结构体来实现堆栈二叉树等数据结构的C语言等

Rat1onal的博客 458

C++ 工程实践(9):数据抽象

陈硕 (giantchen_AT_gmail)http://blog.youkuaiyun.com/Solstice  http://weibo.com/giantchen陈硕关于 C++ 工程实践的系列文章: http://blog.youkuaiyun.com/Solstice/category/8

陈硕的Blog 1万+

C++ STL核心组件解析:容器、算法与迭代器实战指南

在C++编程中,数据结构和算法是构建高效软件的基础。标准模板库(STL)通过泛型编程思想,将常用的数据结构和算法抽象为可复用的组件,实现了数据与操作的分离。其核心包括容器(如vector、map)、算法(如sort、find)和迭代器三大部件,通过迭代器这一统一接口,算法可以独立于具体容器工作,极大提升了代码的通用性和可维护性。从工程实践角度看,理解不同容器的底层实现(如动态数组、红黑树、哈希表)及其时间复杂度特性,是进行性能优化的关键。例如,vector的连续内存特性对CPU缓存友好,而unordered

weixin_33754065的博客 323

AUTOSAR进阶图解==>AUTOSAR_EXP_VFB

AUTOSAR虚拟功能总线(VFB)摘要 AUTOSAR虚拟功能总线(VFB)是汽车开放系统架构中的核心抽象概念,为分布式电子系统提供统一通信模型。VFB允许软件组件在不了解底层物理通信机制的情况下交互,通过运行时环境(RTE)实现组件间的数据交换。系统配置过程将抽象的VFB视图转换为具体实现,包括组件到ECU的映射和通信机制选择。VFB采用"last-is-best"语义进行数据通信,并支持模式管理机制,使组件能根据系统状态调整行为。此外,VFB还支持与非AUTOSAR系统的交互,通常

一名留德华的,康德的信徒的,专注于汽车电子领域的博客 1115

网络系统管理专栏-配套练习+知识点详解

网络系统管理专栏-配套练习+知识点详解

bfq05234214的博客 681

PAT甲级90分选手亲测:用C++刷题,这些STL容器和技巧能帮你省一半时间

本文由PAT甲级90分选手分享C++ STL在算法竞赛中的高效应用,重点解析vector、unordered_map、set等容器的实战技巧,帮助考生在有限时间内提升编码效率。通过具体代码示例展示如何利用STL优化排序、查找等操作,适用于PAT甲级等算法考试。

weixin_30292843的博客 468

ADBC 全面解析:ABAP 开发者玩转 Native SQL 的实战指南

本文介绍了 SAP ABAP 中的 ADBC(ABAP Database Connectivity)技术,它是一种基于 ABAP 面向对象的类库,用于访问 Native SQL 接口。与 Open SQL 和 EXEC SQL 相比,ADBC 具有以下优势:支持特定数据库语法、可访问二级数据库连接、执行多种 SQL 操作且语法更 ABAP 化。文章通过示例展示了 ADBC 的基本用法,包括创建语句对象、执行查询和处理结果集。建议在需要数据库特有功能或二级连接时优先使用 ADBC,同时提供封装类来简化调用。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 305

set和map

insert返回值,是一个pair<iterator,bool>,我们通过调用first,就可以拿到对应key的迭代器,再通过迭代器,就可以访问到这个key所对应的value(通过迭代器.second获得)。set使用count时,依旧传入键值对,也就是value(key),接着count会去set找,传入的值是否存在,如果存在那么会返回1(因为set中数据存在也只会存在一个),不存在就返回0。关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在。

ZCYchecking的博客 1147

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

C++ set与map、unordered_map、unordered_set与哈希表

哈希表 表: 存储数据 key –> value; 用表来存储数据结构的困难:查找困难。一个一个key去比较去查找,效率不高。因此有了Hash算法加快查找; 将字符串的key,转成整数,使用整数找到对应的value;Hash算法将字符串转成整数,同样的Hash值的 key:v...

知识搬运工的博客 2万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

《C++进阶之STL》【unordered_set/unordered_map 使用介绍】

本文介绍了C++ STL中的unordered_set和unordered_map容器。文章详细讲解了其模板参数、构造函数、常用成员函数(如:insert、find、erase等)以及非成员函数重载。通过示例代码展示了默认构造、初始化列表构造、拷贝构造和移动构造等用法,并演示了如何合并两个unordered_set容器。

序属秋秋秋的博客 2784

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【C++篇】无序中的法则:探索 STL之unordered_map 与 unordered_set容器的哈希美学

在高效数据管理的探索中,unordered_map 和 unordered_set 成为 C++ 标准库中的有力工具。通过哈希表实现,它们提供了超快的查找、插入、删除操作,是数据去重、频繁查找以及词频统计等需求的理想选择。本文从基本概念到高级用法,从应用场景到性能分析,深入剖析了这些容器的核心特性,展示了它们如何帮助开发者在效率与简洁之间找到平衡。无论是算法竞赛还是实际开发,掌握 unordered_map 和 unordered_set 都能为你的代码增添新维度的灵活性和速度。

半截诗的博客~ 7396

【C++】-- STL之unordered_map/unordered_set详解

STL有两种容器:序列式容器和关联式容器,序列式容器vetor/lost/deque,用来存储数据。关联式容器map/set/unordered_map/unordered_set用来存储数据+查找数据。 unordered_map和unordered_set是c++里面两个提供哈希表的容器,map和set底层是红黑树,unordered_map和unordered_set的底层是哈希表(散列表),是一种映射。

局部变量和全局变量 2792

【C++深度探索】unordered_set、unordered_map封装

unordered_map和unordered_set的底层都是使用哈希表来实现的,然后在外面套了一层壳,为了能够更好的实现代码复用,我们对哈希表进行了很多修改还使用了仿函数,封装了普通迭代器和const迭代器等,最终成功对unordered_map和unordered_set实现了封装

Renswc的博客 2867

《C++进阶之STL》【unordered_set/unordered_map 模拟实现】

本文介绍了C++标准库中unordered_set和unordered_map的底层实现原理。通过分析SGI-STL30版本的源代码,展示了哈希表hash_set和hash_map的核心结构设计。文章还详细解析了hashtable的关键实现细节,包括节点结构、迭代器设计等核心内容,帮助读者深入理解unordered容器的底层机制。

序属秋秋秋的博客 1906

用哈希表封装unordered_map与unordered_set

但是SGI-STL30实现了哈希表,只容器的名字是hash_map和hash_set,他是作为⾮标准的容器出现的,⾮标准是指⾮C++标准规定必须实现的,源代码在hash_map/hash_set/stl_hash_map/stl_hash_set/stl_hashtable.h中。这⾥的难点是反⽽是结构设计的问题,参考上⾯的源码,我们可以看到iterator中除了有结点的指针,还有哈希表对象的指针,这样当前桶⾛完了,要计算下⼀个桶就相对容易多了,⽤key值计算出当前桶位置,依次往后找下⼀个不为空的桶即可。

2401_87257864的博客 2907
上一篇: 哈希表原理与开放定址法C++实现
下一篇: 哈希表原理与实现_链地址法
jinyishu_
博客等级 码龄1年 53粉丝 82原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值