c++语言中,multiset是<set>库中一个非常有用的类型,它可以看成一个序列,插入一个数,删除一个数都能够在O(logn)的时间内完成,而且他能时刻保证序列中的数是有序的,而且序列中可以存在重复的数。

简单应用:

通过一个程序来看如何使用multiset:

 
#include <string>

#include <iostream>
#include <set>
using namespace std;
void main(){
intx;
scanf("%ld",&x);
multiset<int>h; //建立一个multiset类型,变量名是h,h序列里面存的是int类型,初始h为空
while(x!=0){
h.insert(x); //将x插入h中
scanf("%ld",&x);
}
while(!h.empty()){ // 序列非空 h.empty()==true时 表示h已经空了
__typeof(h.begin()) c=h.begin();
//c指向h序列中第一个元素的地址,第一个元素是最小的元素
printf("%ld ",*c); //将地址c存的数据输出
h.erase(c); //从h序列中将c指向的元素删除
}
}

对于输入数据:32 61 12 2 12 0,该程序的输出是:2 12 12 32 61。

放入自定义类型的数据:

不只是int类型,multiset还可以存储其他的类型诸如 string类型,结构(struct或class)类型。而我们一般在编程当中遇到的问题经常用到自定义的类型,即struct或class。例如下面的例子:

struct rec{

int x,y;
};
multiset<rec>h;

不过以上的代码是没有任何用处的,因为multiset并不知道如何去比较一个自定义的类型。怎么办呢?我们可以定义multiset里面rec类型变量之间的小于关系的含义(这里以x为第一关键字为例),具体过程如下:

定义一个比较类cmp,cmp内部的operator函数的作用是比较rec类型a和b的大小(以x为第一关键字,y为第二关键字):

 
struct cmp{

bool operator()(const rec&a,const rec&b){
return a.x<b.x||a.x==b.x&&a.y<b.y;
}
};

然后将语句"multiset<rec>h ;”改成"multiset<rec,cmp>h;"这样以后,我们就告诉了序列h如何去比较里面的元素(重载运算符)

此时rec以及multiset的定义部分完整代码可参考如下:

struct rec{

int x,y;

};

struct cmp{

bool operator()(const rec&a,const rec&b){

return a.x<b.x||a.x==b.x&&a.y<b.y;

    }

};

multiset<rec,cmp>h;

通过以上代码,能够建立一个集合h使得该集合能够存储和排序自定义类型

常用函数总结:

构造、拷贝、析构

操作

效果

set c

产生一个空的set/multiset,不含任何元素

set c(op)

以op为排序准则,产生一个空的set/multiset

set c1(c2)

产生某个set/multiset的副本,所有元素都被拷贝

set c(beg,end)

以区间[beg,end)内的所有元素产生一个set/multiset

set c(beg,end, op)

以op为排序准则,区间[beg,end)内的元素产生一个set/multiset

c.~set()

销毁所有元素,释放内存

set<Elem>

产生一个set,以(operator <)为排序准则

set<Elem,0p>

产生一个set,以op为排序准则

非变动性操作

操作效果

c.size()

返回当前的元素数量

c.empty ()

判断大小是否为零,等同于0 == size(),效率更高

c.max_size()

返回能容纳的元素最大数量

c1 == c2

判断c1是否等于c2

c1 != c2

判断c1是否不等于c2(等同于!(c1==c2))

c1 < c2

判断c1是否小于c2

c1 > c2

判断c1是否大于c2

c1 <= c2

判断c1是否小于等于c2(等同于!(c2<c1))

c1 >= c2

判断c1是否大于等于c2 (等同于!(c1<c2))

特殊的搜寻函数

  sets和multisets在元素快速搜寻方面做了优化设计,提供了特殊的搜寻函数,所以应优先使用这些搜寻函数,可获得对数复杂度,而非STL的线性复杂度。比如在1000个元素搜寻,对数复杂度平均十次,而线性复杂度平均需要500次。

操作

效果

count (elem)

返回元素值为elem的个数

find(elem)

返回元素值为elem的第一个元素,如果没有返回end()

lower _bound(elem)

返回元素值为elem的第一个可安插位置,也就是元素值 >= elem的第一个元素位置

upper _bound (elem)

返回元素值为elem的最后一个可安插位置,也就是元素值 > elem 的第一个元素位置

equal_range (elem)

返回elem可安插的第一个位置和最后一个位置,也就是元素值==elem的区间

赋值

操作效果

c1 = c2

将c2的元素全部给c1

c1.swap(c2)

将c1和c2 的元素互换

swap(c1,c2)

同上,全局函数

迭代器相关函数

  sets和multisets的迭代器是双向迭代器,对迭代器操作而言,所有的元素都被视为常数,可以确保你不会人为改变元素值,从而打乱既定顺序,所以无法调用变动性算法,如remove()。

操作效果

c.begin()

返回一个随机存取迭代器,指向第一个元素

c.end()

返回一个随机存取迭代器,指向最后一个元素的下一个位置

c.rbegin()

返回一个逆向迭代器,指向逆向迭代的第一个元素

c.rend()

返回一个逆向迭代器,指向逆向迭代的最后一个元素的下一个位置

安插和删除元素

  必须保证参数有效,迭代器必须指向有效位置,序列起点不能位于终点之后,不能从空容器删除元素。

c.insert(elem)

插入一个elem副本,返回新元素位置,无论插入成功与否。

c.insert(pos, elem)

安插一个elem元素副本,返回新元素位置,pos为收索起点,提升插入速度。

c.insert(beg,end)

将区间[beg,end)所有的元素安插到c,无返回值。

c.erase(elem)

删除与elem相等的所有元素,返回被移除的元素个数。

c.erase(pos)

移除迭代器pos所指位置元素,无返回值。

c.erase(beg,end)

移除区间[beg,end)所有元素,无返回值。

c.clear()

移除所有元素,将容器清空

multiset用法汇总的更多相关文章

  1. Linux中find命令的用法汇总

    Linux中find命令的用法汇总 https://www.jb51.net/article/108198.htm

  2. Python Enum 枚举 用法汇总

    Python Enum 枚举 用法汇总 import os import sys if sys.version_info.major + sys.version_info.minor * 0.1 &l ...

  3. C#中DllImport用法汇总

    最近使用DllImport,从网上google后发现,大部分内容都是相同,又从MSDN中搜集下,现将内容汇总,与大家分享. 大家在实际工作学习C#的时候,可能会问:为什么我们要为一些已经存在的功能(比 ...

  4. [STL]set/multiset用法详解[自从VS2010开始,set的iterator类型自动就是const的引用类型]

    集合 使用set或multiset之前,必须加入头文件<set> Set.multiset都是集合类,差别在与set中不允许有重复元素,multiset中允许有重复元素. sets和mul ...

  5. Hibernate 注解中CascadeType用法汇总

    这两天,参加一个课程设计,同时这个项目又作为一个模块镶嵌到其他项目中,考虑如此,应与原先的架构相同,因牵扯到留言和相互@功能,故数据库之间OneToOne,OneToMany,ManyToMany之风 ...

  6. Java Stream常见用法汇总,开发效率大幅提升

    本文已经收录到Github仓库,该仓库包含计算机基础.Java基础.多线程.JVM.数据库.Redis.Spring.Mybatis.SpringMVC.SpringBoot.分布式.微服务.设计模式 ...

  7. BeanShell用法汇总(部分摘抄至网络)【转】

    说明:本文部分资料摘抄至 来源: http://www.cnblogs.com/puresoul/p/4915350.html 来源: http://www.cnblogs.com/puresoul/ ...

  8. 正则表达式常用用法汇总 __西科大C语言

    正则表达式,又称正规表示法.常规表示法.(英语:Regular Expression,在代码中常简写为regex.regexp或RE),计算机科学的一个概念.正则表达式使用单个字符串来描述.匹配一系列 ...

  9. XStream 用法汇总

            XStream是一家Java对象和XML转换工具,很好很强大.它提供了所有的基本型.排列.收集和其他类型的支持,直接转换.因此XML在数据交换经常使用.对象序列化(和Java对象的序列 ...

  10. 常用php时间函数用法汇总

    1.设置时区的方法: php5后都要自己设置时区,要么修改php.ini的设置,要么在代码里修改. 在PHP.INI中设置时区 date.timezone = PRC 在代码中设置时区 1 date_ ...

随机推荐

  1. 【WebSocket】多节点下WebSocket消息收发解决案例

    单体Webscoket springboot版本: 2.1.1.RELEASE jdk: 1.8 示例代码 WebsocketServer @ServerEndpoint("/client/ ...

  2. Hexo博客yilia主题首页添加helper-live2d模型插件

    插件效果 插件的github地址 插件作者提供了较为详细的安装步骤,我结合自己操作和图示,提供大家. 效果展示:红框内为2d模型,可以随鼠标移动而变化 安装模块: hexo博客根目录选择cmd命令窗口 ...

  3. Lakehouse: A New Generation of Open Platforms that Unify Data Warehousing and Advanced Analytics

    在Delta Lake官网上提到的一篇新一代湖仓架构的论文. 这篇论文由Databricks团队2021年发表于CIDR会议. 这个会议是对sigmod和vldb会议的补充. 可以看到这篇论文和前一篇 ...

  4. 2023年ccpc河南省程序设计竞赛-clk

    很荣幸能够参加这次比赛,比赛机会挺难得得,还是第一次线下参加这样的大型比赛,比赛体验自然无话可说比较刺激..这次比赛我和队友crf和nhr共同解决了三道题,参与感极差,可以说问题很大,最简单的签到题我 ...

  5. Centos7下Oracle启动命令

    1.查询挂载历史记录 在root账户下使用一下命令 查看历史使用挂载的那个磁盘 # 查看挂载历史命令 history | grep mount # 调用挂载历史命令,主要是为了找到挂载Oracle的磁 ...

  6. C++(类成员的访问控制)

    访问控制 如下代码,Student这个类的所有成员我们都可以调用,但是我们不想让被人调用Print1这个方法该怎么? struct Student { int age; int sex; void P ...

  7. AI视频风格转换:Stable Diffusion+EBSynth

    这次转换的视频还比较稳定,先给大家看下效果. 这里传不了视频,还是放到盘盘了:https://www.aliyundrive.com/s/5mzfjLViyDa 书接上文,在上一篇文章中,我们首先使用 ...

  8. openlayers学习笔记

    https://www.cnblogs.com/suRimn/p/10649816.html

  9. IOS App内嵌H5 swiper 轮播出现卡顿白屏闪烁

    话说在前头:前端开发同学遇到这个问题不慌,因为接下来你要踩的坑我都帮你们踩完了,所以有了这一篇博客.希望能帮到你 轮播组件:swiper@4.5.1 (4x稳定的最后一个版本) 设备:ios版本15x ...

  10. 发现了一个可以免费下载jar包的网站,所有jar包都有

    苦苦找不到项目所需要的jar包?发现了一个可以免费下载jar包的网站: https://jar-download.com/ 非常好用. 每个JAR文件都将从官方Maven存储库下载.通过下载所有Mav ...