C++之set/multiset容器

简介: C++之set/multiset容器

一、概念

set/multiset:所有元素都会在插入时自动排序,自定义数据类型构造时,需要指定排序规则。

二、构造与赋值

 //遍历输出
void printSet(const set<int> &s) {
    for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}
 
//set容器构造和赋值
void test01() {
    set<int> s1;
 
    //插入数据 只有insert方式
    s1.insert(10);
    s1.insert(30);
    s1.insert(50);
    s1.insert(30);
    s1.insert(40);
    s1.insert(20);
    // set容器特点,所有元素插入时候自动排序,不允许插入重复数据
    printSet(s1);
    // 拷贝构造
    set<int> s2(s1);
    printSet(s2);
    // 赋值
    set<int> s3;
    s3 = s2;
    printSet(s3);
}
 

三、大小与交换

//set的大小与交换
void test02() {
    set<int> s1;
    set<int> s2;
    s1.insert(1);
    s1.insert(2);
    s1.insert(3);
    s2.insert(100);
    s2.insert(200);
    s2.insert(300);
    cout << "s1大小:" << s1.size() << endl;
    cout << "s1是否为空:" << s1.empty() << endl;
    cout << "交换前:" << endl;
    printSet(s1);
    printSet(s2);
    s1.swap(s2);
    cout << "交换后:" << endl;
    printSet(s1);
    printSet(s2);
}

四、插入与删除

//set的插入和删除
void test03() {
    set<int> s1;
    s1.insert(10);
    s1.insert(30);
    s1.insert(50);
    s1.insert(30);
    s1.insert(40);
    s1.insert(20);
    // 遍历
    printSet(s1);
    // 删除
    s1.erase(s1.begin());
    printSet(s1);
    // 删除一个值
    s1.erase(30);
    printSet(s1);
    // 删除一个区间
    s1.erase(s1.begin(), s1.end());
    // 清空
    s1.clear();
    printSet(s1);
}

五、查找与统计

//set查找和统计
void test04() {
    set<int> s1;
    s1.insert(10);
    s1.insert(30);
    s1.insert(50);
    s1.insert(30);
    s1.insert(40);
    s1.insert(20);
    printSet(s1);
    set<int>::iterator it = s1.find(10);
    if (it != s1.end()) {
        cout << "存在元素" << *it << endl;
    } else {
        cout << "不存在元素" << endl;
    }
    cout << "统计 20 出现的次数" << s1.count(20) << endl;
    cout << "统计 200 出现的次数" << s1.count(200) << endl;
}


六、set与multiset区别

set不可以插入重复数据,而multiset可以;

set插入数据的同时会返回插入结果,表示插入是否成功;

multiset不会检测数据,因此可以插入重复数据;

//set和multiset区别
void test05() {
    set<int> s1;
    //接收set插入返回的数据
    pair<set<int>::iterator, bool> ret = s1.insert(10);
    if (ret.second) {
        cout << "第一次插入成功" << endl;
    } else {
        cout << "第一次插入失败" << endl;
    }
    pair<set<int>::iterator, bool> ret2 = s1.insert(10);
    if (ret2.second) {
        cout << "第二次插入成功" << endl;
    } else {
        cout << "第二次插入失败" << endl;
    }
 
    multiset<int> mus1;
    //接收set插入返回的数据
    mus1.insert(10);
    mus1.insert(10);
    mus1.insert(10);
    cout << mus1.size() << endl;
}

七、pair对组创建

//pair对组创建 成对出现的数据,利用对组可以返回两个数据
void test06() {
    pair<string, int> p("tom", 20);
    cout << p.first << " " << p.second << endl;
 
    pair<string, int> p2 = make_pair("jerry", 10);
    cout << p2.first << " " << p2.second << endl;
 
}

八、set容器排序

1、内置数据

//内置数据,修改排序规则
class MyCompare {
public:
    // 仿函数,重载()
    bool operator()(int v1, int v2) const {
        return v1 > v2;
    }
};
 
void test07() {
    set<int> s1;
    s1.insert(1);
    s1.insert(2);
    s1.insert(3);
    s1.insert(4);
    s1.insert(5);
    printSet(s1);
 
    // 自定义排序规则
    set<int, MyCompare> s2;
    s2.insert(1);
    s2.insert(2);
    s2.insert(3);
    s2.insert(4);
    s2.insert(5);
    for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
 
 
}

2、自定义数据

//自定义类型数据,指定排序规则
class Person {
public:
    Person(string name, int age) {
        this->m_Name = name;
        this->m_Age = age;
    }
 
    string m_Name;
    int m_Age;
};
 
class MyCompareT {
public:
    // 仿函数,重载()
    bool operator()(const Person &v1, const Person &v2) const {
        return v1.m_Age < v2.m_Age;
    }
};
 
void test08() {
    // 自定义的数据类型,都会指定排序规则
    set<Person, MyCompareT> s1;
    Person p1("刘备", 35);
    Person p2("曹操", 45);
    Person p3("孙权", 40);
    Person p4("赵云", 25);
    Person p5("张飞", 35);
    Person p6("关羽", 35);
    s1.insert(p1);
    s1.insert(p2);
    s1.insert(p3);
    s1.insert(p4);
    s1.insert(p5);
    s1.insert(p6);
    for (set<Person, MyCompareT>::iterator it = s1.begin(); it != s1.end(); it++) {
        cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << endl;
    }
}

九、全部代码

#include <iostream>
#include <set>
#include <string>
 
using namespace std;
 
//遍历输出
void printSet(const set<int> &s) {
    for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}
 
//set容器构造和赋值
void test01() {
    set<int> s1;
 
    //插入数据 只有insert方式
    s1.insert(10);
    s1.insert(30);
    s1.insert(50);
    s1.insert(30);
    s1.insert(40);
    s1.insert(20);
    // set容器特点,所有元素插入时候自动排序,不允许插入重复数据
    printSet(s1);
    // 拷贝构造
    set<int> s2(s1);
    printSet(s2);
    // 赋值
    set<int> s3;
    s3 = s2;
    printSet(s3);
}
 
//set的大小与交换
void test02() {
    set<int> s1;
    set<int> s2;
    s1.insert(1);
    s1.insert(2);
    s1.insert(3);
    s2.insert(100);
    s2.insert(200);
    s2.insert(300);
    cout << "s1大小:" << s1.size() << endl;
    cout << "s1是否为空:" << s1.empty() << endl;
    cout << "交换前:" << endl;
    printSet(s1);
    printSet(s2);
    s1.swap(s2);
    cout << "交换后:" << endl;
    printSet(s1);
    printSet(s2);
}
 
//set的插入和删除
void test03() {
    set<int> s1;
    s1.insert(10);
    s1.insert(30);
    s1.insert(50);
    s1.insert(30);
    s1.insert(40);
    s1.insert(20);
    // 遍历
    printSet(s1);
    // 删除
    s1.erase(s1.begin());
    printSet(s1);
    // 删除一个值
    s1.erase(30);
    printSet(s1);
    // 删除一个区间
    s1.erase(s1.begin(), s1.end());
    // 清空
    s1.clear();
    printSet(s1);
}
 
//set查找和统计
void test04() {
    set<int> s1;
    s1.insert(10);
    s1.insert(30);
    s1.insert(50);
    s1.insert(30);
    s1.insert(40);
    s1.insert(20);
    printSet(s1);
    set<int>::iterator it = s1.find(10);
    if (it != s1.end()) {
        cout << "存在元素" << *it << endl;
    } else {
        cout << "不存在元素" << endl;
    }
    cout << "统计 20 出现的次数" << s1.count(20) << endl;
    cout << "统计 200 出现的次数" << s1.count(200) << endl;
}
 
//set和multiset区别
void test05() {
    set<int> s1;
    //接收set插入返回的数据
    pair<set<int>::iterator, bool> ret = s1.insert(10);
    if (ret.second) {
        cout << "第一次插入成功" << endl;
    } else {
        cout << "第一次插入失败" << endl;
    }
    pair<set<int>::iterator, bool> ret2 = s1.insert(10);
    if (ret2.second) {
        cout << "第二次插入成功" << endl;
    } else {
        cout << "第二次插入失败" << endl;
    }
 
    multiset<int> mus1;
    //接收set插入返回的数据
    mus1.insert(10);
    mus1.insert(10);
    mus1.insert(10);
    cout << mus1.size() << endl;
}
 
//pair对组创建 成对出现的数据,利用对组可以返回两个数据
void test06() {
    pair<string, int> p("tom", 20);
    cout << p.first << " " << p.second << endl;
 
    pair<string, int> p2 = make_pair("jerry", 10);
    cout << p2.first << " " << p2.second << endl;
 
}
 
//内置数据,修改排序规则
class MyCompare {
public:
    // 仿函数,重载()
    bool operator()(int v1, int v2) const {
        return v1 > v2;
    }
};
 
void test07() {
    set<int> s1;
    s1.insert(1);
    s1.insert(2);
    s1.insert(3);
    s1.insert(4);
    s1.insert(5);
    printSet(s1);
 
    // 自定义排序规则
    set<int, MyCompare> s2;
    s2.insert(1);
    s2.insert(2);
    s2.insert(3);
    s2.insert(4);
    s2.insert(5);
    for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
 
 
}
 
//自定义类型数据,指定排序规则
class Person {
public:
    Person(string name, int age) {
        this->m_Name = name;
        this->m_Age = age;
    }
 
    string m_Name;
    int m_Age;
};
 
class MyCompareT {
public:
    // 仿函数,重载()
    bool operator()(const Person &v1, const Person &v2) const {
        return v1.m_Age < v2.m_Age;
    }
};
 
void test08() {
    // 自定义的数据类型,都会指定排序规则
    set<Person, MyCompareT> s1;
    Person p1("刘备", 35);
    Person p2("曹操", 45);
    Person p3("孙权", 40);
    Person p4("赵云", 25);
    Person p5("张飞", 35);
    Person p6("关羽", 35);
    s1.insert(p1);
    s1.insert(p2);
    s1.insert(p3);
    s1.insert(p4);
    s1.insert(p5);
    s1.insert(p6);
    for (set<Person, MyCompareT>::iterator it = s1.begin(); it != s1.end(); it++) {
        cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << endl;
    }
}
 
int main() {
    // test01();
    // test02();
    // test03();
    // test04();
    // test05();
    // test06();
    // test07();
    test08();
    system("pause");
    return 0;
}
 

相关文章
|
4月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
100 2
|
3月前
|
存储 设计模式 C++
【C++】优先级队列(容器适配器)
本文介绍了C++ STL中的线性容器及其适配器,包括栈、队列和优先队列的设计与实现。详细解析了`deque`的特点和存储结构,以及如何利用`deque`实现栈、队列和优先队列。通过自定义命名空间和类模板,展示了如何模拟实现这些容器适配器,重点讲解了优先队列的内部机制,如堆的构建与维护方法。
60 0
|
4月前
|
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容器编排
131 3
|
4月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
90 5
|
4月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
103 2
|
4月前
|
设计模式 存储 C++
【C++】C++ STL探索:容器适配器 Stack 与 Queue 的使用及模拟实现(二)
【C++】C++ STL探索:容器适配器 Stack 与 Queue 的使用及模拟实现
|
4月前
|
存储 C++ 容器
【C++】C++ STL探索:容器适配器 Stack 与 Queue 的使用及模拟实现(一)
【C++】C++ STL探索:容器适配器 Stack 与 Queue 的使用及模拟实现
|
6月前
|
安全 编译器 容器
C++STL容器和智能指针
C++STL容器和智能指针
|
4天前
|
Ubuntu API 网络虚拟化
ubuntu22 编译安装docker,和docker容器方式安装 deepseek
本脚本适用于Ubuntu 22.04,主要功能包括编译安装Docker和安装DeepSeek模型。首先通过Apt源配置安装Docker,确保网络稳定(建议使用VPN)。接着下载并配置Docker二进制文件,创建Docker用户组并设置守护进程。随后拉取Debian 12镜像,安装系统必备工具,配置Ollama模型管理器,并最终部署和运行DeepSeek模型,提供API接口进行交互测试。
90 15
|
2月前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
296 78