草庐IT

STL容器之<multimap>

SiveenWS 2023-04-02 原文

文章目录

测试环境

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

multimap介绍

  1. 关联式容器。
  2. 每个元素都包含用于排序的键和对应的值。
  3. 键值是不要求唯一(map中键要求唯一),同一个键可以对应多个值。
  4. 支持双向迭代器。
  5. 在插入、删除和搜索时间复杂度为log(n)。
  6. 键不可以直接修改,需要先删除,再添加;值可以直接修改

头文件

#include <map>

模块类定义

template <typename _Key, typename _Tp, typename _Compare = std::less<_Key>,
	    typename _Alloc = std::allocator<std::pair<const _Key, _Tp> > >
    class multimap{};

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

对象构造

/*构造一个空的map对象*/
std::multimap<int,std::string> multiMap1;
/*构造map对象,默认升序排序*/
std::multimap<int,std::string> multiMap2;
/*拷贝构造函数*/
std::multimap<int,std::string> multiMap3(multiMap1);
/*移动构造函数*/
std::multimap<int,std::string> multiMap4(std::move(multiMap3));
/*初始化列表构造函数*/
std::multimap<int,std::string> multiMap5({{1,"a"},{2,"b"},{3,"c"},{4,"d"},{5,"e"}});
/*初始化列表构造函数,并按升序排序*/
std::multimap<int,std::string,std::greater<int> > multiMap6({{1,"a"},{2,"b"},{3,"c"},{4,"d"},{5,"e"}});
/*指定迭代器范围构造函数*/
std::multimap<int,std::string> multiMap7(multiMap5.begin(), ++multiMap5.begin());
/*指定迭代器并指定排序规则*/
std::multimap<int,std::string> multiMap8(multiMap5.begin(), ++multiMap5.begin(),std::less<int>());

初始化

/*使用初始化列表初始化*/
multiMap1 = {{1,"a"}, {1,"b"}, {2,"c"}, {3,"d"},{4,"m"}};

元素访问

不支持at()函数和下标运算符“[]”获取元素

元素插入和删除

函数返回值功能
clear()清空所有元素
erase()迭代器或删除元素数量清除指定位置的一个元素、通过迭代器指定范围内的元素或通过键删除值
emplace()键值对插入元素。插入成功时第一个元素是指向新插入元素的迭代器,失败时第一个元素是指向以存在元素的迭代器,第二个元素表示插入结果,true成功,false失败。
emplace_hint()迭代器插入成功返回新插入元素的迭代器,插入失败时返回已存在元素的迭代器
insert()键值对、迭代器、无1)在指定位置插入1个元素。2)复制通过迭代器指定范围的元素。3)通过初始化列表插入元素。4)直接插入元素。
/*清空容器*/
multiMap1.clear();
/*直接构造或移动语句插入元素*/
auto ret = multiMap1.emplace(1,"hello");
std::cout << "key:"<<ret->first<<" value:"<<ret->second<<std::endl;
/*直接构造或移动语句在指定位置插入元素*/
auto ret1 = multiMap1.emplace_hint(multiMap1.begin(),1,"word");
std::cout << "key:"<<ret1->first<<" value:"<<ret1->second<<std::endl;
/*插入元素,返回键值对*/
multiMap1.insert({1,"ni hao!"});
multiMap1.insert(std::make_pair<int,std::string>(4,"four"));
/*插入元素,返回迭代器*/
multiMap1.insert(multiMap1.begin(),{0,"zero"});
multiMap1.insert(multiMap1.begin(),std::make_pair<int,std::string>(1,"first"));
/*初始化列表插入,无返回值*/
multiMap1.insert({{2,"two"},{3,"three"},{4,"four"}});
/*使用迭代器指定范围插入元素,无返回值*/
std::multimap<int,std::string> multiMap9{{5,"five"},{6,"six"}};
multiMap1.insert(multiMap9.begin(),multiMap9.end());
/*删除单个元素*/
auto ret2 = multiMap1.erase(multiMap1.begin());
std::cout << "ret2.first:"<<ret2->first<<" ret2.second:"<<ret2->second<<std::endl;
for (auto & item : multiMap1)
{
    std::cout<<"key:"<<item.first<<" value:"<<item.second<<std::endl;
}
/*删除指定范围的元素*/
auto ret3 = multiMap1.erase(multiMap1.begin(), ++multiMap1.begin());
std::cout << "ret3.first:"<<ret3->first<<" ret3.second:"<<ret3->second<<std::endl;
for (auto & item : multiMap1)
{
    std::cout<<"key:"<<item.first<<" value:"<<item.second<<std::endl;
}
/*根据键值删除元素*/
int iCount = multiMap1.erase(1);
std::cout << "iCount:"<<iCount<<std::endl;

元素查找

函数返回值功能
count()std::size_t返回给定键对应元素的数量
find()迭代器查找指定键对应的第一个元素的位置,未找到则返回end()
lower_bound()迭代器查找第一个大于或等于给定键的第一个元素的位置,未找到则返回end()
upper_bound()迭代器查找第一个大于给定键的第一个元素元素的位置,未找到返回end()
equal_range()迭代器获取给定键的lower_bound和upper_bound
multiMapTest = {{1,10},{1,11},{4,12},{1,13},{5,14},{8,15},{7,16},{8,17},{9,18},{9,19}};  
/*判断容器中指定键对应的元素数量*/
std::cout << multiMapTest.count(1)<<std::endl;
/*查找指定键的元素所在的位置*/
int iCount = multiMapTest.count(1);
std::multimap<int,int>::iterator itrRet4 = multiMapTest.find(1);
std::cout << "find():"<<std::endl;
while(iCount--)
{
    std::cout << "key:"<<itrRet4->first<<" value:"<<itrRet4->second<<std::endl;
    itrRet4++;
}
/*查找第一个大于等于给定键的第一个元素的位置*/
std::multimap<int,int>::iterator itrRet5 = multiMapTest.lower_bound(1);
std::cout << "key:"<<itrRet5->first<<" value:"<<itrRet5->second<<std::endl;
/*查找第一个大于给定键的元素的位置*/
std::multimap<int,int>::iterator itrRet6 = multiMapTest.upper_bound(3);
std::cout << "key:"<<itrRet6->first<<" value:"<<itrRet6->second<<std::endl;
/*分别返回lower_bound和upper_bound*/
auto ret7 = multiMapTest.equal_range(1);
std::cout << "lower_bound key:"<<ret7.first->first<<" lower_bound value:"<<ret7.first->second<<std::endl;
std::cout << "upper_bound key:"<<ret7.second->first<<" upper_bound value:"<<ret7.second->second<<std::endl;

容器大小

函数返回值功能
size()std::size_t获取当前容器中的元素数量
empty()bool判断当前容器是否为空,为空返回true,否则返回false
max_size()std::size_t返回容器的最大容量
multiMapTest = {{1,10},{1,11},{4,12},{4,13},{5,14},{8,15},{7,16},{8,17},{9,18},{9,19}};
/*判断元素的数量*/
std::cout<<multiMapTest.size()<<std::endl;
/*判断容器最大能容纳的元素的数量*/
std::cout<<multiMapTest.max_size()<<std::endl;
/*判断容器是否为空*/
std::cout<<std::boolalpha<<multiMapTest.empty()<<std::endl;

迭代器

类型功能
iterator正向访问迭代器。从前向后访问元素,可以读取也可以修改
const_iterator常量正向访问迭代器。从前向后访问元素,只能读取不能修改
reverse_iterator逆向访问迭代器。从后向前访问元素,可以读取也可以修改
const_reverse_iterator常量逆向访问迭代器。从后向前访问元素,只能读取不能修改
函数返回值功能
begin()正向访问迭代器返回指向multimap对象首元素所在位置的迭代器
end()正向访问迭代器返回指向multimap对象末尾元素的下一个位置的迭代器
cbegin()常量正向访问迭代器返回指向multimap对象首元素所在位置的常量迭代器
cend()常量正向访问迭代器返回指向multimap对象末尾元素的下一个位置的迭代器
rbegin()逆向访问迭代器返回指向multimap对象末尾元素位置的迭代器
rend()逆向访问迭代器返回指向multimap对象首元素的前一个位置的迭代器
crbegin()常量逆向访问迭代器返回指向multimap对象末尾元素位置的常量迭代器
crend()常量逆向访问迭代器返回指向multimap对象首元素的前一个位置的常量迭代器
std::multimap<int,int>multiMapTest({{1,11},{1,11},{3,12},{3,13},{9,14},{6,15},{7,16},{6,17},{9,18},{10,19}});
/*正向随机访问迭代器,每个元素+10,并打印输出(1--21 1--21 3--22 3--23 6--25 6--27 7--26 9--24 9--28 10--29)*/
std::multimap<int,int>::iterator itr;
for (itr = multiMapTest.begin(); itr != multiMapTest.end(); itr++)
{
    /* 修改元素值每个元素+10 */
    itr->second += 10; 
    /* 访问元素 */
    std::cout <<"first:"<<itr->first<< " second:"<<itr->second<<std::endl;
}
std::cout<<std::endl;
/*常量正向随机访问迭代器,并打印输出(1--21 1--21 3--22 3--23 6--25 6--27 7--26 9--24 9--28 10--29)*/
std::multimap<int,int>::const_iterator cItr;
for (cItr = multiMapTest.cbegin(); cItr != multiMapTest.cend(); cItr++)
{
    /* 不允许修改值,编译报错 */
    //*cItr += 10; 
    /* 访问元素 */
    std::cout <<"first:"<<cItr->first<< " second:"<<cItr->second<<std::endl;
}
std::cout<<std::endl;
/*逆向随机访问迭代器,每个元素+100,并打印输出(10--129 9--128 9 --124 7--126 6--127 6--125 3--123 3--122 1--121 1--121)*/
std::multimap<int,int>::reverse_iterator rItr;
for (rItr= multiMapTest.rbegin(); rItr!= multiMapTest.rend(); rItr++)
{
    /* 修改元素值 */
    rItr->second += 100; 
    /* 访问元素 */
    std::cout <<"first:"<<rItr->first<< " second:"<<rItr->second<<std::endl;
}
std::cout<<std::endl;
/*常量逆向随机访问迭代器,并打印输出(10--129 9--128 9 --124 7--126 6--127 6--125 3--123 3--122 1--121 1--121)*/
std::multimap<int,int>::const_reverse_iterator crItr;
for (crItr= multiMapTest.crbegin(); crItr!= multiMapTest.crend(); crItr++)
{
    /* 不允许修改元素值, 编译报错 */
    //*crItr += 100; 
    /* 访问元素 */
    std::cout <<"first:"<<crItr->first<< " second:"<<crItr->second<<std::endl;
}
std::cout << std::endl;

其他函数

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

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

std::cout << "multimapSwap2:"<<std::endl;
for (auto &item : multimapSwap2)
{
    std::cout<<"key:"<<item.first<<" value:"<<item.second<<std::endl;
}

有关STL容器之<multimap>的更多相关文章

  1. 在保持文本不透明度的同时,可以使用仅使用HTML制作一个透明的容器? - 2

    我想在保持文本/图像不透明的同时使我的容器背景透明。只能使用HTML做到这一点吗?这是我的代码:看答案我看到了您的问题,如果我正确理解您,我想我知道您可以做什么。我注意到的一件事是,在我进一步走之前,看起来您正在使用引导程序代码。如果您更改了可能与此相关的CSS样式表,则可能会更好,更有效,也可能不会破坏整体代码的其他元素,但是让我们看看我的解决方案是否对您有效。基本上您想做的是:1)在您的HTML中编写一个“样式”标签,然后在其中放入样式(CSS)属性(您可以将其放入HTML代码的标题中以更好地跟踪它)。2)使用提供背景颜色的“RGBA”格式,并将其不透明度为“0”作为代码段的第四值。因此,

  2. ruby-on-rails - 使用 AWS Elastic Beanstalk 和 Ruby 容器设置私有(private) Github 访问 - 2

    经过recenttutorial关于使用Git为Ruby部署设置AWSElasticBeanstalk,我只是从我的CI服务器设置了一个ElasticBeanstalk环境。但是,应用程序无法启动。我查看日志发现bundleinstall失败并显示一条错误消息。Fetchinggit@github.com:example/private-repository.gitHostkeyverificationfailed.fatal:Theremoteendhungupunexpectedly[31mGiterror:commandgitclone'git@github.com:exampl

  3. vue2+element-ui,el-aside侧边栏容器收缩与展开 - 2

    一、概览实现效果如下:二、项目环境1、nodejs版本node-vv16.16.02、npm版本npm-vnpmWARNconfigglobal`--global`,`--local`aredeprecated.Use`--location=global`instead.8.15.03、vue脚手架版本vue-V@vue/cli5.0.8三、创建vue项目1、创建名为vuetest的项目vuecreatevuetest选择Default([Vue2]babel,eslint)  2、切换到项目目录,启动项目cdvuetestnpmrunserve 3、使用浏览器预览 http://localh

  4. ruby - Ruby 有像栈、队列、链表、映射或集合这样的容器吗? - 2

    我在网上查了几个Ruby教程,他们似乎什么都用数组。那么如何在Ruby中实现以下数据结构呢?堆栈队列链表map组 最佳答案 (从评论中移出)好吧,通过限制堆栈或队列方法(push、pop、shift、unshift),数组可以是堆栈或队列。使用push/pop提供LIFO(后进先出)行为(堆栈),而使用push/shift或unshift/pop提供FIFO行为(队列)。map是hashes,和一个Set类已经存在。您可以使用类实现链表,但数组将使用标准数组方法提供类似于链表的行为。 关

  5. javascript - 选择容器中的最后一个词 - 2

    我只是想知道是否有办法选择DIV中的最后一个WORD。我认为没有任何明显的方法可以做到这一点,那么有什么变通办法吗?我不介意使用CSS或Javascript来实现这一点。提前致谢 最佳答案 或者没有,它归结为基本的字符串操作(使用match())方法。varwords=$('#your_div').text().match(/(\w+)/g);if(words.length){varlast_word=words[words.length-1];}我们使用match()构建所有单词的数组方法,然后获取最后一个(varlast_wor

  6. javascript - 使用 Knockout 组件时替换容器元素 - 2

    有没有办法配置Knockoutcomponent替换容器元素而不是将其内容嵌套在容器元素中?例如,如果我使用以下模板将自定义组件注册为my-custom-element:Helloworld!是否可以像这样使用组件:最终产品是这样的:Helloworld!而不是这样:(Knockout默认渲染组件的方式)Helloworld!Basedontheanswertothisquestion,似乎此功能内置于模板引擎中,我假设在呈现组件模板时也会使用它。有没有一种方法可以指定组件应该使用replaceNode的renderMode进行渲染?我知道“虚拟元素”语法,它允许在HTML注释中定义组

  7. javascript - ReactJS - ReactMount : Root element has been removed from its original container. 新容器 - 2

    这个错误是什么意思?如何解决?ReactMount:Rootelementhasbeenremovedfromitsoriginalcontainer.Newcontainer在这之后我得到了这个:Uncaughtobjectreact.js:15915invariantreact.js:15915ReactMount.findComponentRootreact.js:10584ReactMount.findReactNodeByIDreact.js:10480getNodereact.js:10089(anonymousfunction)react.js:7307(anonymou

  8. javascript - 在 docker 容器中安装 yarn 说缺少依赖 - 2

    我正在使用node:6.7.0图像作为我的docker容器,然后按照yarn的安装指南进行操作sudoapt-keyadv--keyserverpgp.mit.edu--recvD101F7899D41F3C3echo"debhttp://dl.yarnpkg.com/debian/stablemain"|sudotee/etc/apt/sources.list.d/yarn.list然后我做apt-getupdate&&apt-getinstallyarn但此时我收到一条错误消息,上面写着yarn:Depends:nodejs(>=4.0.0)butitisnotgoingtobei

  9. javascript - 如何将输入字段数据从模态传递到 react-Native 中的容器? - 2

    这是我正在使用的:{}}>在容器中我不知道如何将数据从模态传递到父组件。任何类型的教程或链接都可以。提前致谢。 最佳答案 让我们假设您的模态框在/components/MyModal中单独归档以概括事物。您可以让您的Modal调用一个函数,在每次输入文本更改时通过props传递该函数。这是您可以使用的简单回调逻辑。尽可能避免使用refs。importMyModalfrom'../components/MyModal';...classHomeextendsComponent{onInputChanged=(changedText)=

  10. javascript - 在 CSS 中保持纵横比的同时将图像调整到容器大小? - 2

    我有一堆不同(未知)尺寸的图像。我想将这些图像放到一个div中,并让它们自动符合div的尺寸,同时保持它们的纵横比。换句话说,如果图像宽度大于高度,则宽度将为100%,高度将相应缩放。如果图像高于宽度,高度将为100%,宽度将相应缩放。有没有办法在纯css中做到这一点?谢谢 最佳答案 使用css属性max-width和max-height图片上的图标将带您到达您需要去的地方。fiddlehttp://fiddle.jshell.net/sHAQ9/HTMLCSSdiv{width:150px;height:150px;overflo

随机推荐