Multiset的中文名是多重集合,其实就是集合的扩展版。唯一的不同是集合中一个值只能出现一次,而多重集合中一个值可以出现多次。

  粗略看了看MSDN,在STL中,multiset和set的成员函数声明也是基本一样的,一些需要注意的地方是:

  • set::insert(key)的返回值是一个pair<iterator, bool>,其中pair中的bool成员表明了key被插入之前,set中是否已存在相同的key。根据我在VS2010上的实验结果,如果set中已经存在相同key的元素,那么插入操作是会失败的,新的元素不会被插进去。而multiset::insert的返回值只是一个iterator,插入操作总是会成功的。
  • multiset::count(key)的返回值可能大于1。
  • multiset::size()的返回值是多重集合的势(cardinality),即multiset中元素的个数,而不是值的个数。比如,{1, 1, 2}的size是3,而不是2。
  • multiset::erase(key)会将对应的key全部删掉,所以对{1, 1, 2}调用erase(1)之后,它就变成了{2}。
  • 只要key存在于集合中,set::equal_range(key)的返回值pair<iterator1, iterator2>总是会有++iterator1 == iterator2。但是对multiset来说就不一定了。

  什么时候需要用multiset?当然是需要用set,但是又允许重复key存在的时候了。什么时候用set?我的答案是:需要随时往容器中插入元素,随时对元素进行快速查找,又需要按某种顺序对元素进行遍历的时候——如果没有第三项需求的话可以用非标准库的hash_或标准库的unordered_开头的容器。

  举一个Wikipedia上的例子:假设我们需要将一个很大的数n分解为多个质数因子的乘积,并将这些质数因子存储在容器中,供以后查询和遍历用。比如对于n = 120 = 2 x 2 x 2 x 3 x 5,我们可以将它的质数因子存储为primeFactorMultiset = { 2, 2, 2, 3, 5 }。当然也可以用map,将质数因子本身存为key,将该因子的出现次数存为value。但是考虑一下下面的需求:

  • 我们想知道n可以分解为多少个质数因子的乘积。如果用map的话,代码如下:
int numPrimeFactors = 0;
for (auto iter = primeFactorMap.begin(); primeFactorMap.end() != iter; ++iter)
{numPrimeFactors += iter->second;
}

for循环执行完后的numPrimeFactors才是我们想要的结果。

如果用multiset,我们只需要调用primeFactorMultiset.size()。

  • 我们想打印出2 2 2 3 5这样的序列。

用map要两重循环:

for (auto iter = primeFactorMap.begin(); primeFactorMap.end() != iter; ++iter)
{for (int i = 0; i < iter->second; ++i){cout << iter->first << ' ';}
}

用multiset只要一重循环,代码又简洁了一点:

for (auto iter = primeFactorMultiset.begin(); primeFactorMultiset.end() != iter; ++iter)
{cout << *iter << ' ';
}

Multiset(中)——STL中的multiset相关推荐

  1. C++中STL中的大、小、相等概念

    1.STL的大.小.相等概念 STL中关联容器内部的元素是排序的.STL中的许多算法也涉及排序.查找.这些容器和算法都需要对元素进行比较,有的比较是否相等,有的比较元素大小. 在STL中,默认情况下, ...

  2. 关于STL中的map和hash_map

    在网上看到有关STL中hash_map的文章,以及一些其他关于STL map和hash_map的资料,总结笔记如下:     1.STL的map底层是用红黑树实现的,查找时间复杂度是log(n):   ...

  3. STL中的set容器的一点总结

    1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...

  4. 理解stl中的erase

    vector<Path *> vec; vec.push_back(new Path); vec.erase(vec.begin()); vector<Path > vec; ...

  5. C++ STL中哈希表 hash_map介绍

    0 为什么需要hash_map 用过map吧?map提供一个很常用的功能,那就是提供key-value的存储和查找功能.例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改: 岳不群-华 ...

  6. c++STL中的find()函数 有两种使用方法

    c++STL中的find()函数 有两种使用方法 方法一: 开头引头文件:中的函数 其调用形式为 find(start,end,value) start搜寻的起点,end搜寻的终点,要寻找的value ...

  7. php的set 容器,关于STL中set容器的一些总结

    1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...

  8. 红黑树实现——STL中的map

    From: http://blog.csdn.net/zhongjiekangping/article/details/6934571 红黑树实现--STL中的map [ 2009-07-24 13: ...

  9. STL set和multiset

    *************************************************** 更多精彩,欢迎进入:http://shop115376623.taobao.com STL视频教 ...

最新文章

  1. dataset存入mysql_将dataset写入数据库
  2. 一些免费收费api收藏
  3. python水仙花数
  4. 数据库 索引超出了数组界限
  5. kali之msfconsole
  6. 对冲基金小镇 鬼城_未来系统,代码寿命和网络鬼城
  7. osl倒数第三层_原子最外层、次外层及倒数第三层最多容纳电子数的解释
  8. 美术 2.4 UV原理基础
  9. Apache的Order Allow,Deny 配置详解
  10. python type() 判断数据类型
  11. sed 注释行的 方法
  12. Win10 忘记开机密码的解决办法(亲测可用)
  13. 【JS】js的urlencode编码
  14. 基于bytom 智能合约_基于HTTP的合约测试@ Gamesys
  15. Travel SCU - 4444
  16. 颈椎不太好适合学计算机那,低头对颈椎不好,那仰头是不是有好处?保护颈椎要记住5个要点,10个动作!...
  17. Ubuntu 18.04安装远程桌面
  18. 广告费的分摊计提 预提?NO
  19. 使用agg方法聚合数据
  20. Five Below IPO路演PPT及注释

热门文章

  1. 2023网站接入谷歌广告教程
  2. (二维数组打表)F. 342 and Xiangqi
  3. 林地府邸java什么版本_《我的世界》林地府邸究竟有什么秘密?这4个屋子千万不能错过!...
  4. 工作小记:redirectTo,relaunch,switchTab
  5. Unity工程代码规范检测工具
  6. 论文阅读:Deep Learning with Differential Privacy
  7. iphone启用证书_如何在iPhone上启用低数据模式
  8. RESTFul接口规范
  9. python中生成藏头诗
  10. linux格式化磁盘命令(磁盘分区及格式化)