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;
}
 

相关文章
|
2月前
|
C++ 容器
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——AVL树
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——AVL树
27 5
|
2月前
|
存储 C++ 索引
|
3月前
|
存储 C++ 容器
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
46 5
|
2月前
|
安全 编译器 容器
C++STL容器和智能指针
C++STL容器和智能指针
|
2月前
|
C++ 容器
C++中自定义结构体或类作为关联容器的键
C++中自定义结构体或类作为关联容器的键
35 0
|
2月前
|
存储 缓存 NoSQL
【C++】哈希容器
【C++】哈希容器
|
2月前
|
关系型数据库 C++ 容器
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——红黑树
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——红黑树
28 0
|
15天前
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
60 30
|
4天前
|
并行计算 Unix Linux
超级好用的C++实用库之线程基类
超级好用的C++实用库之线程基类
12 4
|
4天前
|
C++ Windows
HTML+JavaScript构建C++类代码一键转换MASM32代码平台
HTML+JavaScript构建C++类代码一键转换MASM32代码平台
下一篇
无影云桌面