STL-set/multiset集合容器

简介: STL-set/multiset集合容器

特点:

  • 所有元素在插入时会被自动排序

本质:

  • set/multiset属于关联式容器,底层结构使用二叉树实现

set和multiset区别:

  • set不允许容器中有重复的元素
  • multiset允许容器中有重复元素

set构造和赋值

构造:

  • set<T>st;//默认构造函数
  • set(const set& st);//拷贝构造函数

赋值:

  • set& operator=(const set& st);//重载等号运算符

set插入数据只有.insert(elem)方法

set<int>l;
//准备数据
l.insert(3);
l.insert(2);
l.insert(4);
l.insert(5);
l.insert(1);
//set容器不允许插入重复值,虽然没有报错,但也插不成功
l.insert(1);
for (set<int>::iterator it = l.begin(); it != l.end(); it++)
{
    cout << *it << " ";//1 2 3 4 5
}

set大小和交换

  • .size();//返回容器中元素个数
  • .empty();//判断容器是否为空
  • .swap(st);//交换两个集合容器

没有.resize()方法:

  • 剩余部分用0填充,与set不允许重复这一特性矛盾
#include <iostream>
#include<set>
#include<string>
using namespace std;
void PrintSet(const set<int>& st)
{
    //可以不用只读迭代器
    for (set<int>::const_iterator it = st.begin(); it != st.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl << st.size() << " " << st.empty() << endl;
}
int main()
{
    set<int>st;
    st.insert(2);
    st.insert(1);
    st.insert(3);
    st.insert(5);
    st.insert(4);
    PrintSet(st);
    set<int>st1;
    for (int i = 0; i < 10; i++)
    {
        st1.insert(i);
    }
    PrintSet(st1);
    st.swap(st1);
    PrintSet(st);
    PrintSet(st1);
    return 0;
}

set插入和删除

  • .insert(elem);//在容器中插入元素
  • .clear();//清除所有元素
  • .erase(pos);//删除pos迭代器所指的元素,返回下一个元素的迭代器
  • .erase(beg, end);//删除[beg,end)区间内的元素,返回下一个元素的迭代器
  • .erase(elem);//删除容器中值为elem的元素
  • 类似于list容器中的.remove(elem);方法

set查找和统计

  • .find(key);//查找key是否存在,若存在,返回该元素的迭代器,若不存在,返回.end()
  • .count(key);//统计key的个数
  • 由于set不允许插入重复值,因此结果只有0或1
set<int>st;
st.insert(2);
st.insert(1);
st.insert(3);
st.insert(5);
st.insert(4);
//查找
//由于find返回值是一个迭代器,所以也需要创建一个迭代器来接收它
set<int>::iterator pos = st.find(4);
if (pos != st.end())
    cout << "找到了" << *pos << endl;
else
    cout << "没找到" << endl;
//统计
cout << st.count(3) << endl;

set和multiset区别

  • set不可以插入重复数据,multiset可以
  • set插入数据的同时会返回插入结果,表示插入是否成功
  • multiset不会检测数据,因此可以插入重复数据
set<int>st;
//set容器插入的返回值是pair,有两个参数:迭代器和布尔
pair<set<int>::iterator,bool>ret= st.insert(4);
if (ret.second)
    cout << "插入成功" << endl;//√
else
    cout << "插入失败" << endl;
ret = st.insert(4);
if (ret.second)
    cout << "插入成功" << endl;
else
    cout << "插入失败" << endl;//√
//multiset插入的返回值是一个迭代器,不会进行判断,插多少是多少

pair对组创建

成对出现的数据,利用对组可以返回两个数据

两种创建方式:

  • pair<type, type>p(value1, value2);
  • pair<type, type>p = make_pair(value1, value2);
//创建pair
pair<string, int>p1("张三", 10);
pair<string, int>p2 = make_pair("李四", 20);
//通过.first和.second访问
cout << p1.first << p1.second << endl;
p2.first = p1.first;
cout << p2.first << p2.second << endl;

set容器指定排序规则

利用仿函数,可以改变排序规则

仿函数就是重载()运算符

内置数据类型自定义排序

函数名后需要加const修饰

  • 在仿函数中,对于传入的参数进行操作时,如果没有加上const,那么默认这个参数是可以被修改的。
  • 而在set容器中,元素是不允许修改的,所以如果仿函数中没有加上const,会与set容器的实现矛盾,导致编译错误。
  • 而加上const则表示这个参数是只读的,不会对其进行修改,就能避免这个错误。
#include <iostream>
#include<set>
#include<string>
using namespace std;
//set容器排序
class MyCompare
{
public:
    //不加const会报错
    bool operator()(int v1, int v2)const
    {
        return v1 > v2;
    }
};
int main()
{
    set<int>s1;
    s1.insert(10);
    s1.insert(30);
    s1.insert(20);
    //默认规则为从小到大
    for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;
    //指定排序规则为从大到小
    set<int, MyCompare>s2;
    s2.insert(10);
    s2.insert(30);
    s2.insert(20);
    for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++)
    {
        cout << *it << " ";
    }
    return 0;
}

自定义数据类型排序

对于自定义数据类型,都会指定排序规则,否则编译器不知道该按照什么排序

#include<iostream>
#include<set>
#include<string>
using namespace std;
class Person
{
public:
    Person(string name, int age)
    {
        this->m_name = name;
        this->m_age = age;
    }
    string m_name;
    int m_age;
};
//set容器排序
class ComparePerson
{
public:
    //不加const会报错
    bool operator()(const Person& p1, const Person& p2)const
    {
        return p1.m_age > p2.m_age;
    }
};
int main()
{
    set<Person, ComparePerson>s;
    Person p1("A", 10);
    Person p2("B", 30);
    Person p3("C", 20);
    Person p4("D", 40);
    Person p5("E", 40);
    s.insert(p1);
    s.insert(p2);
    s.insert(p3);
    s.insert(p4);
    s.insert(p5);//由于p4,p4的年龄相同,p5会插入失败
    for (set<Person, ComparePerson>::iterator it = s.begin(); it != s.end(); it++)
    {
        cout << (*it).m_name << " " << (*it).m_age << endl;
    }
    return 0;
}
目录
相关文章
|
存储 Java 容器
HashMap 的基本操作【集合容器知识回顾 ⑤】
本文介绍了HashMap的基本操作,包括创建对象、添加、获取、删除和替换元素、获取所有key的集合、遍历HashMap,以及如何存储自定义类型键值对,并强调了当使用自定义对象作为键时需要重写equals和hashCode方法以确保正确的行为。
HashMap 的基本操作【集合容器知识回顾 ⑤】
|
7月前
|
存储 编译器 容器
set、map、multiset、multimap的介绍及使用以及区别,注意事项
set是按照一定次序存储元素的容器,使用set的迭代器遍历set中的元素,可以得到有序序列。set当中存储元素的value都是唯一的,不可以重复,因此可以使用set进行去重。set默认是升序的,但是其内部默认不是按照大于比较,而是按照小于比较。set中的元素不能被修改,因为set在底层是用二叉搜索树来实现的,若是对二叉搜索树当中某个结点的值进行了修改,那么这棵树将不再是二叉搜索树。
284 0
|
10月前
|
存储 算法 C++
【c++丨STL】set/multiset的使用
本文深入解析了STL中的`set`和`multiset`容器,二者均为关联式容器,底层基于红黑树实现。`set`支持唯一性元素存储并自动排序,适用于高效查找场景;`multiset`允许重复元素。两者均具备O(logN)的插入、删除与查找复杂度。文章详细介绍了构造函数、迭代器、容量接口、增删操作(如`insert`、`erase`)、查找统计(如`find`、`count`)及`multiset`特有的区间操作(如`lower_bound`、`upper_bound`、`equal_range`)。最后预告了`map`容器的学习,其作为键值对存储的关联式容器,同样基于红黑树,具有高效操作特性。
461 3
|
Kubernetes Cloud Native 流计算
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
395 3
|
存储 Java 容器
HashSet 的基本操作【集合容器知识回顾 ④】
本文介绍了HashSet的基本操作,包括创建和初始化、添加和删除元素、判断元素存在性、获取集合大小、遍历、求交集差集、转换为数组和其他集合类型、比较两个HashSet,以及如何将自定义对象作为HashSet的元素时重写hashCode和equals方法,最后总结了HashSet的性能特点和使用注意事项。
HashSet 的基本操作【集合容器知识回顾 ④】
|
存储 安全 Java
ArrayList的基本操作【集合容器知识回顾 ②】
这篇文章详细介绍了ArrayList的基本操作,包括创建对象、添加和删除元素、获取和更新元素、遍历、判断元素存在性、集合的空值检查、批量操作、转换为数组、截取子集合、查找元素索引、克隆拷贝、清空集合以及容量管理等,同时指出了使用ArrayList时的注意事项,如线程安全性、容量管理、删除元素的性能、遍历时的修改、空值处理和性能优化。
ArrayList的基本操作【集合容器知识回顾 ②】
|
Java API 索引
LinkedList的基本操作【集合容器知识回顾 ③】
本文详细介绍了LinkedList的基本操作,包括初始化、添加、获取、删除、替换元素、遍历,以及LinkedList独有的队列和栈相关操作,同时指出了LinkedList在插入和删除操作方面的优势以及在随机访问元素时的性能劣势。
|
3月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
298 1
|
6月前
|
存储 缓存 JavaScript
Set和Map有什么区别?
Set和Map有什么区别?
509 1
|
3月前
|
存储 算法 容器
set_map的实现+set/map加持秒杀高频算法题锻炼算法思维
`set`基于红黑树实现,支持有序存储、自动去重,增删查效率为O(logN)。通过仿函数可自定义排序规则,配合空间配置器灵活管理内存。不支持修改元素值,迭代器失效需注意。`multiset`允许重复元素。常用于去重、排序及查找场景。