STL容器之<unordered_multimap>

测试环境

系统:ubuntu 22.04.2 LTS 64位
gcc版本:11.3.0
编辑器:vsCode 1.76.2

unordered_multimap介绍

  1. 关联式容器。
  2. 每个元素都包含一个键和对应的值。
  3. 元素是无序的。
  4. 键可以不唯一,一个键可以对应多个值。
  5. 支持单向迭代器。
  6. 插入元素时不会使迭代器失效,删除元素时会使指向已删除元素的迭代器失效。
  7. 插入、删除和查找元素时间复杂度为O(1),最坏情况下为O(n)。

头文件

#include <unordered_map>

模块类定义

template<typename _Key, typename _Tp,
	   typename _Hash = hash<_Key>,
	   typename _Pred = equal_to<_Key>,
	   typename _Alloc = allocator<std::pair<const _Key, _Tp>>>
    class unordered_multimap{};

_Key:表示存储的键数据类型
_Tp:表示存储的值的数据类型
_Hash:哈希函数对象类型
_Pred:表示按照键的排序方式。
_Alloc:表示所存储分配器的类型,负责元素内存的分配和释放。可选参数,一般不使用。

对象构造

/*构造一个空的map对象*/
std::unordered_multimap<int,std::string> unordermultimap1;

/*构造map对象,指定最小桶数量*/
std::unordered_multimap<int,std::string> unordermultimap2(10);

/*拷贝构造函数*/
std::unordered_multimap<int,std::string> unordermultimap3(unordermultimap1);

/*移动构造函数*/
std::unordered_multimap<int,std::string> unordermultimap4(std::move(unordermultimap1));

/*初始化列表构造函数*/
std::unordered_multimap<int,std::string> unordermultimap5({{1,"a"},{2,"b"},{3,"c"},{4,"d"},{4,"e"}});

/*指定迭代器范围构造函数*/
std::unordered_multimap<int,std::string> unordermultimap6(++unordermultimap5.begin(), unordermultimap5.end());

初始化

/*初始化列表初始化*/
std::unordered_multimap<int,std::string> unordermultimapTest({{6,"a"},{7,"b"},{8,"c"},{10,"d"},{10,"e"},{1,"f"},{2,"g"},{3,"h"},{5,"i"},{5,"g"}});

元素访问

不支持at()和[]访问元素。

元素插入和删除

函数返回值功能
clear()清空所有元素
erase()迭代器或删除元素数量清除指定位置的一个元素、通过迭代器指定范围内的元素或通过键删除值
emplace()迭代器插入元素,并返回指向被插入元素在容器中的位置。
emplace_hint()迭代器插入成功返回新插入元素的迭代器,插入失败时返回已存在元素的迭代器
insert()迭代器1)在指定位置插入1个元素。2)复制通过迭代器指定范围的元素。3)通过初始化列表插入元素。4)直接插入元素。
/*直接构造并插入元素*/
std::unordered_multimap<int,std::string>::iterator itr1 = unordermultimapTest.emplace(1,"a");
std::cout << "emplace key is "<<itr1->first<<" emplace value is "<<itr1->second<<std::endl;

/*直接构造并插入元素*/
std::pair<int,std::string> pair1(1, "b");
std::unordered_multimap<int,std::string>::iterator itr2 = unordermultimapTest.emplace(std::move(pair1));
std::cout << "itr2 key is "<<itr2->first<<" itr2 value is "<<itr2->second<<std::endl;

/*直接构造并在指定位置插入元素*/
std::unordered_multimap<int,std::string>::iterator itr3 = unordermultimapTest.emplace_hint(++unordermultimapTest.begin(),8,"b");
std::cout << "itr3 key is "<<itr1->first<<" itr3 value is "<<itr1->second<<std::endl;
    
/*删除单个元素*/
std::unordered_multimap<int,std::string>::iterator itr4 = unordermultimapTest.erase(unordermultimapTest.begin());
std::cout << "itr4 key is "<<itr4->first<<" itr4 value is "<<itr2->second<<std::endl;

/*删除指定范围的元素*/
std::unordered_multimap<int,std::string>::iterator itr5 = unordermultimapTest.erase(unordermultimapTest.begin(), ++unordermultimapTest.begin());
std::cout << "itr5 key is "<<itr5->first<<" itr5 value is "<<itr5->second<<std::endl;

/*根据键值删除元素*/
int iCount = unordermultimapTest.erase(1);
std::cout << "erace element count is "<<iCount<<std::endl;

/*清空元素*/
unordermultimapTest.clear();

/*插入元素,返回键值对*/
std::unordered_multimap<int,std::string>::iterator itr6 = unordermultimapTest.insert({1,"hello"});
std::cout << "itr6 key is "<<itr6->first<<" itr6 value is "<<itr6->second<<std::endl;

/*使用移动语句插入元素,返回键值对*/
std::pair<int,std::string> pair3(2,"world");
std::unordered_multimap<int,std::string>::iterator itr7 = unordermultimapTest.insert(std::move(pair3));
std::cout << "itr7 key is "<<itr7->first<<" itr7 value is "<<itr7->second<<std::endl;

/*插入元素,返回迭代器*/
std::unordered_multimap<int,std::string>::iterator itr8 = unordermultimapTest.insert(unordermultimapTest.begin(),{3,"three"});
std::cout << "itr8 key is "<< itr8->first << ",itr8 value is "<<itr8->second<<std::endl;

/*使用移动语句插入元素,返回迭代器*/
std::pair<int,std::string> pair7(4,"four");
std::unordered_multimap<int,std::string>::iterator itr9 = unordermultimapTest.insert(unordermultimapTest.begin(),std::move(pair7));
std::cout << "itr9 key is "<< itr9->first << ",itr9 value is "<<itr9->second<<std::endl;

/*初始化列表插入,无返回值*/
unordermultimapTest.insert({{5,"one"},{7,"two"},{6,"three"}});

/*使用迭代器指定范围插入元素,无返回值*/
std::unordered_multimap<int,std::string> unordermultimap8{{3,"three"},{4,"four"}};
unordermultimapTest.insert(unordermultimap8.begin(),unordermultimap8.end());

元素查找

函数返回值功能
count()std::size_t返回给定键对应元素的数量
find()迭代器查找指定键对应元素的位置,未找到则返回end()
equal_range()键值对查找与指定键匹配的范围
/*判断某个键对应值的数量*/
std::cout<<unordermultimapTest.count(3)<<std::endl;

/*查找指定键的元素所在的位置*/
std::unordered_multimap<int,std::string>::iterator itr10 = unordermultimapTest.find(4);
std::cout<<"find key is "<<itr10->first<<",find value is "<<itr10->second<<std::endl;

/*返回给定键的范围*/
std::pair<std::unordered_map<int,std::string>::iterator, \
       std::unordered_map<int,std::string>::iterator> pair4 = unordermultimapTest.equal_range(4);
if (unordermultimapTest.end() != pair4.first && unordermultimapTest.end() != pair4.second)
{
   for (; pair4.first != pair4.second; pair4.first++ )
   {
       std::cout<<"key is "<<pair4.first->first<<",value is "<<pair4.first->second<<std::endl;
   }
}

容器大小

函数返回值功能
size()std::size_t获取当前容器中的元素数量
empty()bool判断当前容器是否为空,为空返回true,否则返回false
max_size()std::size_t返回容器的最大容量
unordermultimapTest = {{1,"hi"},{2,"hao"},{5,"zhong"},{4,"guo"},{3,"2023"}};
/*判断元素的数量*/
std::cout<<unordermultimapTest.size()<<std::endl;

/*判断容器最大能容纳的元素的数量*/
std::cout<<unordermultimapTest.max_size()<<std::endl;

/*判断容器是否为空*/
std::cout<<std::boolalpha<<unordermultimapTest.empty()<<std::endl;

迭代器

类型功能
iterator正向访问迭代器。从前向后访问元素,可以读取也可以修改
const_iterator常量正向访问迭代器。从前向后访问元素,只能读取不能修改
函数返回值功能
begin()正向访问迭代器返回指向unorder_multimap对象首元素所在位置的迭代器
end()正向访问迭代器返回指向unorder_multimap对象末尾元素的下一个位置的迭代器
cbegin()常量正向访问迭代器返回指向unorder_multimap对象首元素所在位置的常量迭代器
cend()常量正向访问迭代器返回指向unorder_multimap对象末尾元素的下一个位置的迭代器
std::unordered_multimap<int,std::string> unordermultimapTest({{6,"a"},{7,"b"},{8,"c"},{10,"d"},{10,"e"},{1,"f"},{2,"g"},{3,"h"},{5,"i"},{5,"g"}});
/*常量正向随机访问迭代器*/
std::unordered_multimap<int,std::string>::const_iterator cItr;
for (cItr = unordermultimapTest.cbegin(); cItr != unordermultimapTest.cend(); cItr++)
{
    /* 不允许修改值,编译报错 */
    //*cItr += 10; 
    /* 访问元素 */
    std::cout <<"first:"<< cItr->first<< " second:"<<cItr->second<<std::endl;
}
std::cout<<std::endl;

/*正向随机访问迭代器,每个元素后追加a*/
std::unordered_multimap<int,std::string>::iterator itr;
for (itr = unordermultimapTest.begin(); itr != unordermultimapTest.end(); itr++)
{
    /* 修改元素值每个元素后补充一个a*/
    itr->second += "a"; 
    /* 访问元素 */
    std::cout <<"first:"<<itr->first<< " second:"<<itr->second<<std::endl;;
}
std::cout<<std::endl;

元素交换

函数名返回值功能
swap()交换两个容器的元素
/*交互两个容器元素的值,无返回值*/
std::unordered_multimap<int,int> unordermultimapSwap1 = {{1,6},{2,6},{3,6},{4,6},{5,6}};
std::unordered_multimap<int,int> unordermultimapSwap2 = {{1,8},{2,8},{3,8},{4,8},{5,8}};
/*方式1, unordermultimapSwap1={{1,8},{2,8},{3,8},{4,8},{5,8}}, unordermultimapSwap2={{1,6},{2,6},{3,6},{4,6},{5,6}}*/
unordermultimapSwap1.swap(unordermultimapSwap2);
std::cout << "unordermultimapSwap1: "<<std::endl;
for (auto &item : unordermultimapSwap1)
{
    std::cout<<"key:"<<item.first<<" value:"<<item.second<<std::endl;
}
std::cout << "unordermultimapSwap2: "<<std::endl;
for (auto &item : unordermultimapSwap2)
{
    std::cout<<"key:"<<item.first<<" value:"<<item.second<<std::endl;
}

/*unordermultimapSwap1={{1,6},{2,6},{3,6},{4,6},{5,6}}, unordermultimapSwap2={{1,8},{2,8},{3,8},{4,8},{5,8}}*/
std::swap(unordermultimapSwap1,unordermultimapSwap2);
std::cout << "unordermultimapSwap1: "<<std::endl;
for (auto &item : unordermultimapSwap1)
{
    std::cout<<"key:"<<item.first<<" value:"<<item.second<<std::endl;
}
std::cout << "unordermultimapSwap2: "<<std::endl;
for (auto &item : unordermultimapSwap2)
{
    std::cout<<"key:"<<item.first<<" value:"<<item.second<<std::endl;
}

其他函数

函数名返回值功能
bucket()std::size_type获取给定键对应的存储桶的编号
bucket_count()std::size_type获取hash表的存储桶的总数量
bucket_size()std::size_type根据存储桶的编号获取存储桶的大小
load_factor()float获取每个存储桶的平均元素数量
max_bucket_count()std::size_type获取当前允许的最大存储桶数量
max_load_factor()float或无获取或者设置每个存储桶的最大元素数量
rehash()根据指定的存储桶数量重新生成hash表

注:桶即指的哈希桶,详情自行查找学习哈希算法相关知识。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值