一,set和multiset的基础知识

1.set和multiset的基础

  • set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按照一定的顺序排列,元素插入过程是按照排序规则插入的。所以不能指定插入元素的位置。
  • set的底层数据结构是红黑二叉树,红黑树属于平衡二叉树。在插入操作和删除操作比vector快。
  • set不可以直接存取元素,即不能使用像序列式容器中(vector,deque)那样随机存取。
  • multiset和set的区别在于set支持元素唯一,而multiset允许插入多个重复的元素。
  • 不可以直接修改set和multiset容器中的元素值,因为该类容器是自动排序的,如果想要修改某个元素的值,需要先删除该元素,然后再重新插入新的元素。
  • 要使用set或者multiset要引入的头文件是# include<set>。

2.函数对象的基础知识

  set集合默认是从小到大的顺序排序的,如果我们存储的是学生类,想要自定义排序,那么STL提供了函数对象这个概念,所谓的函数对象就是重载了结构体的()操作符。然后返回结果是bool类型。

二,set和multiset的代码示例

1.set和multiset的基本比较

# include<iostream>
# include<set>
# include<string> using namespace std; int main01()
{
// 定义set集合
set<string> s1;
// 定义multiset集合
multiset<string> s2; // 往set集合中插入元素,其返回结果是一个pair,包含插入进去后的迭代器以及是否插入成功的标志
pair<set<string>::iterator, bool> p1 = s1.insert("Hello");
cout << *p1.first << "," << p1.second << endl;
// 我们发现往set集合中插入相同的元素会插入不成功
pair<set<string>::iterator, bool> p2 = s1.insert("Hello");
cout << *p2.first << "," << p2.second << endl;
// 遍历
for (string tmp : s1)
{
cout << tmp << endl;
}
// 我们往multiset集合中插入元素
s2.insert("Hello");
s2.insert("Hello");
for (string tmp : s2)
{
cout << tmp << endl;
} return ;
}

2.set集合的遍历

# include<iostream>
# include<string>
# include<set>
using namespace std; int main02()
{
// 定义集合
set<string> s;
// 插入集合
s.insert("Hello");
s.insert("world");
s.insert("C++");
// 增强for遍历
for (string tmp : s)
{
cout << tmp << " ";
}
cout << endl;
// 迭代器正向遍历
for (set<string>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << " ";
}
cout << endl;
// 迭代器逆向遍历
for (set<string>::reverse_iterator it = s.rbegin(); it != s.rend(); it++)
{
cout << *it << " ";
}
cout << endl; return ;
}

3.set集合的删除

# include<iostream>
# include<set>
# include<string> using namespace std; int main03()
{
// 创建集合
set<string> s;
// 插入元素
s.insert("Hello");
s.insert("World");
s.insert("Unreal");
s.insert("C++");
// 删除元素World
for (set<string>::iterator it = s.begin(); it != s.end();)
{
if (*it == "World")
{
it = s.erase(it);
}
else {
it++;
}
}
// 输出集合的长度
int size1 = s.size();
cout << "size1 = " << size1 << endl;
// 遍历元素删除
set<string>::iterator it = s.begin();
while (!s.empty())
{
cout << *it << endl;
it = s.erase(it);
}
// 输出集合的长度
int size2 = s.size();
cout << "size = " << size2 << endl; return ;
}

4.set常用的函数

# include<iostream>
# include<set>
# include<string> using namespace std; int main04()
{
// set集合默认是从小到大排序的
set<int> s;
// 插入元素
s.insert();
s.insert();
s.insert();
s.insert();
// 遍历元素
for (int tmp : s)
{
cout << tmp << " ";
}
cout << endl;
// 统计元素出现的次数
int cs = s.count();
cout << "cs = " << cs << endl;
// 查找元素为2的迭代器
set<int>::iterator it = s.find();
cout << *it << endl; return ;
}

5.自定义函数对象实现对学生类的排序

# include<iostream>
# include<string>
# include<set>
using namespace std;
/*
定义学生类,按照其年龄进行排序
*/
class Student
{
public:
string name;
int age;
public:
Student(string name, int age)
{
this->name = name;
this->age = age;
}
};
/*
定义函数对象:所谓的函数对象,就是重载了()操作符的结构体
*/
struct StudentFunctor
{
bool operator()(const Student& stu1,const Student& stu2)
{
// 如果是>则是从大到小排序,如果是<则是从小到大排序
return stu1.age > stu2.age;
}
}; int main()
{
// 定义学生集合
set<Student,StudentFunctor> s;
// 插入学生
s.insert(Student("张飞",));
s.insert(Student("关羽", ));
s.insert(Student("赵云", ));
s.insert(Student("马超", ));
// 打印学生
for (Student stu : s)
{
cout << stu.name << " = " << stu.age << endl;
} return ;
}

STL关联式容器之set和multiset的更多相关文章

  1. STL关联式容器之set\map ----以STL源码为例

    关联式容器的特征:所用元素都会根据元素的键值自动被排序. set STL 中的关联式容器低层数据结构为红黑树,其功能都是调用低层数据结构中提供的相应接口. set元的元素不会像map那样同时拥有键(k ...

  2. STL关联式容器之map和multimap

    一,map和multimap的概念 1.map和multimap的基本知识 map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对.它提供基于key的快速检索能力. map中 ...

  3. STL序列式容器之list

    一,list容器基本概念 1.list容器基本知识 list容器的底部数据结构为双向链表,可以高效的进行插入和删除元素. list因为底层数据结构是双向链表,因此不支持下标操作和.at()函数的操作. ...

  4. STL——关联式容器

    一.关联式容器 标准的STL关联式容器分为set(集合)/map(映射表)两大类,以及这两大类的衍生体multiset(多键集合)和 multimap(多键映射表).这些容器的底层机制均以RB-tre ...

  5. C++ 序列式容器之vector

     什么是容器 容器,顾名思义,是用来容放东西的场所.C++容器容放某种数据结构,以利于对数据的搜寻或排序或其他特殊目的.众所周知,常用的数据结构不外乎:数组array,  链表list,  树tree ...

  6. STL的六大容器之iterator----自定义范式

    STL的iterator组件,分离了容器和算法. 一.规定 在STL体系下定义iterator,要满足规定的一些规范: 1.iterator_category 有5中分类,决定胃具体的操作,如:++, ...

  7. 关联式容器(associative containers)

    关联式容器(associative containers) 根据数据在容器中的排列特性,容器可分为序列式(sequence)和关联式(associative)两种. 标准的STL关联式容器分为set( ...

  8. iBinary C++STL模板库关联容器之map/multimap

    目录 一丶关联容器map/multimap 容器 二丶代码例子 1.map的三种插入数据的方法 3.map集合的遍历 4.验证map集合数据是否插入成功 5.map数据的查找 6.Map集合删除元素以 ...

  9. [知识点]C++中STL容器之map

    UPDATE(20190416):写完vector和set之后,发现不少内容全部引导到map上了……于是进行了一定的描述补充与更正. 零.STL目录 1.容器之map 2.容器之vector 3.容器 ...

随机推荐

  1. vivado中basic memory生成

    vivado中basic memory生成

  2. 解决安装mysql-connector-odbc-5.3.2 错误1918……不能载入安装或转换器库……的BUG

    还是在虚拟机Windows Server 2003上安装mysql-connector-odbc-5.3.2,装着装着就报错了,大致是"错误1918--不能载入安装或转换器库--" ...

  3. 关于Android中设置闹钟的相对完善的解决方案

    前些时候,有人在我「非著名程序员」微信公众号的后台问我有没有设置闹钟的demo,我当时说承诺为大家写一个,一直没空,直到最近又有人跟我要,我决定抽时间写一个吧.确实设置闹钟是一个比较麻烦的东西.我在这 ...

  4. 最简单的基于FFmpeg的移动端样例:IOS HelloWorld

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  5. andorid 自己定义SwitchButton

    因项目缘故需又一次定制SwitchButton,效果例如以下:   步骤例如以下: 1.圆角矩形的绘制 2.字体绘制 3.小圆绘制 4.左右滑动动画效果绘制 代码例如以下: package com.s ...

  6. swift学习第八天:元组

    元组的介绍 元组是Swift中特有的,OC中并没有相关类型 它是什么呢? 它是一种数据结构,在数学中应用广泛 类似于数组或者字典 可以用于定义一组数据 组成元组类型的数据可以称为“元素” 元组的定义 ...

  7. Jcaptca 图片

    http://www.oschina.net/code/snippet_89964_6009 http://blog.csdn.net/tender001/article/details/846969 ...

  8. jquery平滑滚动页面

    滚动到顶部 $('.scroll_top').click(function(){$('html,body').animate({scrollTop: '0px'}, 800);}); 滚动到指定位置 ...

  9. Android注冊短信验证码功能

    一.短信验证的效果是通过使用聚合数据的SDK实现的 ,效果例如以下: 二.依据前一段时间的博客中输了怎么注冊! 注冊之后找到个人中心找到申请一个应用就可以! 三.依据官方文档创建项目 官方文档API下 ...

  10. SetProcessWorkingSetSize() 方法使内存降低了很多(把内存放到交换区,其实会降低性能)——打开后长时间不使用软件,会有很长时间的加载过程,原来是这个!

    在项目中对程序性能优化时,发现用SetProcessWorkingSetSize() 方法使内存降低了很多,于是查阅了相关的资料如下: 我的程序为什么能够将占用的内存移至虚拟内存呢? 其实,你也可以, ...