【C++学习笔记】:set容器

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 在STL中,set是一种按照特定顺序存储唯一元素的容器容器。可以实现存储数据、检索数据等功能。

1、写在前面

大家好,今天文章的内容是:

  • Set容器

2、内容


2.1、介绍

在STL中,set是一种按照特定顺序存储唯一元素的容器容器。可以实现存储数据、检索数据等功能。

注意事项:

  • 不能直接修改set中的元素值,正确的做法是删除旧值,再插入更新后的值。
  • set中的数据元素具有唯一性,各个元素的值必须不同。
  • set中的元素被用作数据自动排序所依据的键值。也就是说,使用set容器存储的各个键值对,键key和值value是相等的。此时,根据key排序也就等同于根据value排序

2.2、set类

(1) 语法

set类的语法如下:

template <class T,
    class Traits = less<T>,
    class Allocator = allocator<T>>
class set

(2) 参数

Key

Key 指的是在set中存储的元素的数据类型

Traits

Traits 是一种提供函数对象的类型,该函数对象将两个元素值作为排序键进行比较,用于指定set中的排序规则;

备注:

  • Traits 属于可选参数
  • 默认值为less <T>,即升序。
  • 也可以设置为greater<T>,即降序。

Allocator

Allocator 是一种用于表示分配器对象的类型。

备注:

  • Allocator 是可选参数
  • 默认值为allocator<T>
  • 该分配器对象封装了set中的内存分配等信息;

2.3、创建set容器

(1) 导入头文件

因为set容器以类模板set<T>的形式定义在<set>头文件中,并位于std命名空间中。

所以我们在使用set容器之前需要导入以下代码:

#include <set>
using namespace std;

在导入头文件后,就可以使用set容器了。


(2) 举例一

创建一个int类型的set空容器s1,注意,这里是使用了默认的less<int>排序规则

代码:

#include <iostream>
#include <set>
using namespace std;

int main() {
    // 创建set 
    set <int> s1;
    // 此时插入三个元素 
    s1.insert(11);
    s1.insert(22);
    s1.insert(33);
    // 输出s1
    cout << "s1: ";
    for(int i : s1) {
        cout << i << " ";
    } 
    cout << '\n';
    return 0; 
}

运行结果:

s1: 11 22 33

(3) 举例二

创建set容器并用已有的容器进行初始化。

代码:

#include <iostream>
#include <set>
using namespace std;

int main() {
    // 创建set 
    set <int> s1;
    // 此时插入三个元素 
    s1.insert(11);
    s1.insert(22);
    s1.insert(33);
    // 复制 s1 
    set<int> s2(s1);
    // 插入新元素
    s2.insert(44); 
    // 输出s2
    cout << "s2: ";
    for(int i : s2) {
        cout << i << " ";
    } 
    cout << '\n';
    return 0; 
}

运行结果:

s2: 11 22 33 44

(4) 举例三

创建容器并用原有的容器的指定区间 $[first, last)$ 内的元素进行初始化。

注意:区间是左闭右开的。

代码:

#include <iostream>
#include <set>
using namespace std;

int main() {
    // 创建set 
    set <int> s1;
    // 此时插入四个元素 
    s1.insert(11);
    s1.insert(22);
    s1.insert(33);
    s1.insert(44);
    // 创建两个迭代器对象 first 和 last
    set <int>::const_iterator first, last;
    // first 指向容器第一个元素 
    first = s1.begin();
    // last 最后指向了容器的第三个元素 
    last = s1.begin();
    last++;
    last++; 
    // 创建set容器 s3 并使用 s1 指定区间 [first,last)上的元素进行初始化 
    set <int> s3(first, last);
    // 输出s3
    cout << "s3: ";
    for(int i : s3) {
        cout << i << " ";
    } 
    cout << '\n';
    return 0; 
}

运行结果:

s3: 11 22

(5) 举例四

在创建newSet容器并利用数组arr的指定区间中的元素来初始化容器。

代码:

#include <iostream>
#include <set>
using namespace std;

int main() {
    // 先创建一个数组
    int arr[]= {11,22,33,44,55};
    // 创建set容器并用数组中的指定区间进行初始化
    set<int> s4(arr, arr+3);
    // 输出s4
    cout << "s4: ";
    for(int i : s4) {
        cout << i << " ";
    } 
    cout << '\n';
    return 0; 
}

运行结果:

s4: 11 22 33

(6) 举例五

代码:

#include <iostream>
#include <set>
using namespace std;

struct classcomp {
  bool operator() (const int& lhs, const int& rhs) const {
    return lhs > rhs;
  }
};

int main () {
    // 创建set,并使用自定义的排序规则 
    set<int, classcomp> s5;
    // 此时插入三个元素 
    s5.insert(11);
    s5.insert(22);
    s5.insert(33);
    // 输出s5
    cout << "s5: ";
    for(int i : s5) {
        cout << i << " ";
    } 
    cout << '\n';
    return 0;
}

运行结果:

s5: 33 22 11

2.4、成员函数

set的成员函数有很多,这里记录几个常用的。


begin

begin()函数用于返回一个迭代器,指向set中的第一个元素的位置。

备注:

如果使用begin()函数后将返回值赋给了iterator,则可以修改set中的数据元素。但是,如果将begin()函数的返回值赋给const_iterator,则不能修改set中的数据元素。

举个例子:

#include <iostream>
#include <set>
using namespace std;

int main() {
    // 创建一个空的set容器 
    set<int> s1;
    // 插入三个元素 
    s1.insert(100);
    s1.insert(200);
    s1.insert(300);
    // begin()函数返回指向第一个元素的迭代器 
    set<int>::iterator s1_iter = s1.begin();
    // 输出
    cout << "set容器中的第一个数据元素为:" << *s1_iter << endl;
    return 0;
}

运行结果:

set容器中的第一个数据元素为:100

end

end()函数用于返回一个迭代器,指向set中最后一个元素的后一个位置。(注意,不是指向末尾元素)

备注:

  • 如果set是一个空容器,则此时set::end() == set::begin()
  • 使用end()函数,可以判断迭代器是否超过了set的末尾。

erase

erase()函数用于移除指定元素、移除指定位置的元素以及移除指定范围内的元素。

语法如下:

// 移除指定元素
size_type erase(const key_type& key);
// 移除指定位置的元素
iterator erase(const_iterator where);
// 移除指定范围内的元素
iterator erase(const_iterator first, const_iterator last);

举个例子:

#include <iostream>
#include <set>
using namespace std;

void printMySet(const set<int, greater<int>>& s) {
    cout << "[ ";
    for (const auto& iter : s) {
        cout << iter << " ";
    }
    cout<< "]" << endl;
}

int main() {
    // 创建一个容器,并使用降序规则
    set<int, greater<int>> s1;
    // 插入五个元素
    s1.insert(111);
    s1.insert(222);
    s1.insert(333);
    s1.insert(444);
    s1.insert(555);
    cout << "删除前set中的元素为:";
    printMySet(s1);
    s1.erase(333);
    cout << "删除后set中的元素为:";
    printMySet(s1);
    return 0;
}

运行结果:

删除前set中的元素为:[ 555 444 333 222 111 ]
删除后set中的元素为:[ 555 444 222 111 ]

find

find()函数用于从set容器中查找与指定键等效的数据元素,并返回一个迭代器指向其位置。

语法如下:

iterator find(const Key& key);
const_iterator find(const Key& key) const;

举个例子:

#include <iostream>
#include <set>
using namespace std;

void printMySet(const set<int>& s) {
    cout << "set容器中的元素为:[ ";
    for (const auto& iter : s) {
        cout << iter << " ";
    }
    cout<< "]" << endl;
}

void findVal(const set<int>& s, int value) {
    cout << "查找中..." << endl; 
    auto result = s.find(value);
    if(result == s.end()) {
        cout << "找不到指定元素 => (" << value << ")" << endl; 
    }else {
        cout << "已找到指定元素 => (" << value<< ")"<< endl; 
    }
}

int main() {
    // 创建一个空容器 
    set<int> s;
    // 插入五个元素 
    s.insert(111);
    s.insert(222);
    s.insert(333);
    s.insert(444);
    s.insert(555);
    // 打印容器信息 
    printMySet(s);
    // 查找元素 
    findVal(s, 666);
    findVal(s, 333);
    return 0; 
}

运行结果:

set容器中的元素为:[ 111 222 333 444 555 ]
查找中...
找不到指定元素 => (666)
查找中...
已找到指定元素 => (333)

insert

insert()函数可用于插入单个元素、若干个元素以及插入数组中的元素等。

举个例子:

#include<iostream>
#include<set>
#include<vector> 
using namespace std;

void printMySet(const set<int>& s) {
    cout << " 容器中的元素为:[ ";
    for (const auto& iter : s) {
        cout << iter << " ";
    }
    cout<< "]" << endl;
}

int main() {
    // 创建 s1
    set<int> s1;
    // 插入五个元素 (容器中的元素会自动按照一定的顺序排列)
    s1.insert({22, 55, 33, 11, 44});
    // 打印容器信息
    cout << "s1";
    printMySet(s1);
    
    // ==============================
    
    // 创建 s2
    set<int> s2;
    // 创建一个vector数组 
    vector<int> v;
    v.push_back(48);
    v.push_back(64);
    v.push_back(15);
    v.push_back(37);
    v.push_back(88);
    // 插入数组 
    s2.insert(v.begin(), v.end());
    // 打印容器信息
    cout << "s2";
    printMySet(s2);
    
    return 0; 
}

运行结果:

s1 容器中的元素为:[ 11 22 33 44 55 ]
s2 容器中的元素为:[ 15 37 48 64 88 ]

size

size()函数用于返回当前set中的元素个数。

语法如下:

size_type size() const;

举个例子:

#include <set>
#include <iostream>
using namespace std;

void printMySet(const set<int>& s) {
    cout << "容器中的元素为:[ ";
    for (const auto& iter : s) {
        cout << iter << " ";
    }
    cout << "]" << endl;
    cout << "size =  " << s.size() << '\n' <<  endl;
}

int main( ) {
    set<int>s;
    
    s.insert(100);
    printMySet(s);
    
    s.insert(600);
    printMySet(s);
    
    s.insert({400, 500, 300, 200});
    printMySet(s);
    return 0;
}

运行结果:

容器中的元素为:[ 100 ]
size =  1

容器中的元素为:[ 100 600 ]
size =  2

容器中的元素为:[ 100 200 300 400 500 600 ]
size =  6

2.5、小结:

对set容器小结:

  • set容器是一种关联式容器,支持使用键值来高效检索元素值,但需要注意到,set容器的键值就是它的元素值,即set是一种简单的关联式容器。
  • set容器是有序的,其元素在容器中是根据指定的比较函数按键值进行排序的。
  • set容器提供了双向迭代器来访问其元素。
  • set容器中的元素具有唯一性,即每个元素都具有唯一的键。

3、写在最后

好了,今天就先记录到这里,感谢观看。

目录
相关文章
|
存储 消息中间件 调度
【C++】容器篇(三)—— stack的基本介绍及其模拟实现
【C++】容器篇(三)—— stack的基本介绍及其模拟实现
|
25天前
|
设计模式 程序员 C++
【C++ 泛型编程 高级篇】C++模板元编程:使用模板特化 灵活提取嵌套类型与多容器兼容性
【C++ 泛型编程 高级篇】C++模板元编程:使用模板特化 灵活提取嵌套类型与多容器兼容性
241 2
|
3天前
|
程序员 索引 Python
06-python数据容器-set(集合)入门基础操作
06-python数据容器-set(集合)入门基础操作
|
算法 程序员 C语言
【C++ 迭代器】深入探讨 C++ 迭代器:标准与自定义容器中的 begin() 和 cbegin()
【C++ 迭代器】深入探讨 C++ 迭代器:标准与自定义容器中的 begin() 和 cbegin()
46 0
|
25天前
|
存储 安全 编译器
【C++ 17 泛型容器对比】C++ 深度解析:std::any 与 std::variant 的细微差别
【C++ 17 泛型容器对比】C++ 深度解析:std::any 与 std::variant 的细微差别
47 1
|
25天前
|
存储 安全 算法
【C++ 17 包裹类 泛型容器 std::any】深入理解与应用C++ std::any:从泛型编程到多态设计
【C++ 17 包裹类 泛型容器 std::any】深入理解与应用C++ std::any:从泛型编程到多态设计
47 1
|
1月前
|
存储 缓存 调度
C++关联容器深度解析:提升数据结构操作的艺术
C++关联容器深度解析:提升数据结构操作的艺术
74 0
|
1月前
|
安全 算法 调度
C++队列探秘:队列容器的使用技巧与实战案例解析
C++队列探秘:队列容器的使用技巧与实战案例解析
125 0
|
1月前
|
存储 网络协议 C++
C++ Vector容器详解:一站式指南,掌握动态数组的高效使用
C++ Vector容器详解:一站式指南,掌握动态数组的高效使用
49 2
|
1月前
|
存储 缓存 安全
【C/C++ 基础 数组容器比较】深入探究C++容器:数组、vector与array之间的异同
【C/C++ 基础 数组容器比较】深入探究C++容器:数组、vector与array之间的异同
15 0