❤️面向初学者的 STL set 详解,一看就懂!❤️

Posted Linux猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了❤️面向初学者的 STL set 详解,一看就懂!❤️相关的知识,希望对你有一定的参考价值。


 🎈 作者:Linux猿

🎈 简介:CSDN博客专家🏆,C/C++、面试、刷题、算法尽管咨询我,关注我,有问题私聊!

🎈 关注专栏:C/C++面试通关集锦 (优质好文持续更新中……)🚀


目录

一、什么是 set ?

二、set 的定义

2.1 头文件

2.2 定义

2.3 常用方法

三、set 方法实例演示

3.1 size()、clear()、empty() 方法

3.2 begin()、end() 方法

3.3 rbegin()、rend() 方法

3.4 lower_bound()、upper_bound() 方法

3.5 erase 方法

3.5.1 删除指定元素

3.5.2 删去区间[first, last)的元素

3.6 insert 方法

3.7 find 方法

四、总结


set 是 STL 最常使用的容器之一,是在日常使用以及面试中经常遇到的知识点,下面来详细讲解下 set。

一、什么是 set ?

set 是一个集合类型的容器,里面的元素具有唯一性,并且所有元素都会根据元素的键值自动被排序,以红黑树为底层数据结构。

二、set 的定义

2.1 头文件

使用 set 需要引入头文件:

#include <set>

2.2 定义

定义的形式如下所示:

set<T>变量名称;

其中,T 是数据类型,例如:int、char、String、类等。

下面来看一个例子:

#include <iostream>
#include <set>        // set 容器头文件
using namespace std;  // 如果没有这句,则需要使用 std::set

int main() {
    set<int>t1;                      // 定义 set 对象 t1
    set<int>t2{1,2,3};               // 定义 t2,初始值为 {1,2,3}
    set<int>t3(t2);                  // 使用 t2 初始化 t3
    set<int>t4(t2.begin(), t2.end()); // 使用一个区间初始化 t4

    set<int>::iterator iter = t4.begin();
    for(iter = t4.begin(); iter != t4.end(); ++iter) {
        cout<<*iter<<" ";
    }
    cout<<endl;
    // 输出为 1 2 3
}

输出结果为:

linuxy@linuxy:~/STLset$ g++ -o main main.cpp
linuxy@linuxy:~/STLset$ ./main 
1 2 3 
linuxy@linuxy:~/STLset$

2.3 常用方法

size() : 返回容器元素个数
clear() : 清空容器元素
empty() : 判断容器是否为空,空返回 true,否则,返回false
begin() : 返回指向第一个元素的迭代器
end() : 返回指向最后一个元素的迭代器
rbegin() : 返回指向最后一个元素的反向迭代器
rend() : 返回指向第一个元素的反向迭代器
lower_bound() : 返回指向等于或大于指定键值元素的迭代器
upper_bound() : 返回指向大于指定键值元素的迭代器
erase (position) : 删除迭代器 position 指向的元素
erase (first, last) : 删除 [first, last) 区间的元素
insert(val) : 插入元素 val
find (val) : 查找元素 val,如果存在返回其迭代器

 三、set 方法实例演示

3.1 size()、clear()、empty() 方法

函数原型如下所示:

size_type size() const noexcept;    // 返回容器元素个数
void clear() noexcept;                   // 清空容器
bool empty() const noexcept;       // 判断容器是否为空,空返回 true,否则,返回false

下面来看一个例子:

#include <iostream>
#include <set>        // set 容器头文件
using namespace std;  // 没有这句,则需要使用 std::set

int main() {
    set<int>t1;             //定义 set 对象 t1

    cout<<"t1.empty() = "<<t1.empty()<<endl; // 1
    cout<<"t1.size() = "<<t1.size()<<endl;   // 0

    for(int i = 1; i <= 6; ++i) {    // 插入 1 2 3 4 5 6
        t1.insert(i);
    }
    cout<<"-------------------------------"<<endl; // 分割线
    cout<<"t1.empty() = "<<t1.empty()<<endl;       // 0
    cout<<"t1.size() = "<<t1.size()<<endl;         // 6

    cout<<"-------------------------------"<<endl;
    t1.clear();             // 清空元素
    cout<<"t1.empty() = "<<t1.empty()<<endl;  // 1
    cout<<"t1.size() = "<<t1.size()<<endl;    // 0
    return 0;
}

输出结果为:

linuxy@linuxy:~/STLset$ g++ -o main main.cpp
linuxy@linuxy:~/STLset$ ./main 
t1.empty() = 1
t1.size() = 0
-------------------------------
t1.empty() = 0
t1.size() = 6
-------------------------------
t1.empty() = 1
t1.size() = 0
linuxy@linuxy:~/STLset$ 

3.2 begin()、end() 方法

函数原型如下所示:

iterator begin() noexcept;    // 返回指向第一个元素的迭代器
iterator end() noexcept;      // 返回指向最后一个元素的迭代器

下面来看一个例子:

#include <iostream>
#include <set>        // set 容器头文件
using namespace std;  // 没有这句,则需要使用 std::set

int main() {
    set<int>t1;             //定义 set 对象 t1

    for(int i = 1; i <= 6; ++i) {    // 插入 1 2 3 4 5 6
        t1.insert(i);
    }

    set<int>::iterator iter;         // 迭代器
    for(iter = t1.begin(); iter != t1.end(); ++iter) { // 输出所有元素
        cout<<*iter<<" ";
    }
    cout<<endl;
    //输出为:1 2 3 4 5 6
    return 0;
}

输出结果为:

linuxy@linuxy:~/STLset$ g++ -o main main.cpp
linuxy@linuxy:~/STLset$ ./main 
1 2 3 4 5 6 
linuxy@linuxy:~/STLset$ 

3.3 rbegin()、rend() 方法

函数原型如下所示:

reverse_iterator rbegin() noexcept;     // 返回指向最后一个元素的反向迭代器
reverse_iterator rend() noexcept;       // 返回指向第一个元素的反向迭代器

下面来看一个例子:

#include <iostream>
#include <set>        // set 容器头文件
using namespace std;  // 没有这句,则需要使用 std::set

int main() {
    set<int>t1;             //定义 set 对象 t1

    for(int i = 1; i <= 6; ++i) {    // 插入 1 2 3 4 5 6
        t1.insert(i);
    }

    set<int>::reverse_iterator riter;         // 使用反向迭代器
    for(riter = t1.rbegin(); riter != t1.rend(); ++riter) { // 输出所有元素
        cout<<*riter<<" ";
    }
    cout<<endl;
    //输出为:6 5 4 3 2 1
    return 0;
}

输出结果为:

linuxy@linuxy:~/STLset$ g++ -o main main.cpp
linuxy@linuxy:~/STLset$ ./main 
6 5 4 3 2 1 
linuxy@linuxy:~/STLset$

注意:使用反向 迭代器。

3.4 lower_bound()、upper_bound() 方法

函数原型如下所示:

iterator lower_bound (const value_type& val);   // 返回指向等于或大于指定键值元素的迭代器
iterator upper_bound (const value_type& val);   // 返回指向大于指定键值元素的迭代器

下面来看一个简单的例子:

#include <iostream>
#include <set>        // set 容器头文件
using namespace std;  // 没有这句,则需要使用 std::set

int main() {
    set<int>t1;             //定义 set 对象 t1

    for(int i = 1; i <= 6; ++i) {    // 插入 1 2 3 4 5 6
        t1.insert(i);
    }

    set<int>::iterator iter = t1.lower_bound(3); // 返回大于等于 3 的第一个元素的迭代器
    cout<<*iter<<endl;

    iter = t1.upper_bound(3); // 返回大于 3 的第一个元素的迭代器
    cout<<*iter<<endl;
    return 0;
}

输出结果为:

linuxy@linuxy:~/STLset$ g++ -o main main.cpp
linuxy@linuxy:~/STLset$ ./main 
3
4
linuxy@linuxy:~/STLset$

可以看到,lower_bound 返回 3,而 upper_bound 返回 4。

3.5 erase 方法

3.5.1 删除指定元素

函数原型如下所示:

iterator erase (const_iterator position); // 删除迭代器 position 指向的元素

下面来看一个例子:

#include <iostream>
#include <set>        // set 容器头文件
using namespace std;  // 如果没有这句,则需要使用 std::set

int main() {
    set<int>t1;                      // 定义 set 对象 t1

    for(int i = 1; i <= 6; ++i) {    // 插入 1 2 3 4 5 6
        t1.insert(i);
    }

    set<int>::iterator iter = t1.begin();   // 迭代器
    ++iter;
    t1.erase(iter);                  // 删除元素

    for(iter = t1.begin(); iter != t1.end(); ++iter) { // 依次输出元素
        cout<<*iter<<" ";
    }
    cout<<endl;
    // 输出为: 1 3 4 5 6
}

输出结果为:

linuxy@linuxy:~/STLset$ g++ -o main main.cpp
linuxy@linuxy:~/STLset$ ./main 
1 3 4 5 6 
linuxy@linuxy:~/STLset$

3.5.2 删去区间[first, last)的元素

函数原型如下所示:

iterator erase (const_iterator first, const_iterator last); // 删除[first, last)区间的元素

下面来看一个例子:

#include <iostream>
#include <set>        // set 容器头文件
using namespace std;  // 如果没有这句,则需要使用 std::set

int main() {
    set<int>t1;                      // 定义 set 对象 t1

    for(int i = 1; i <= 6; ++i) {    // 插入 1 2 3 4 5 6
        t1.insert(i);
    }

    set<int>::iterator iter2 = t1.begin(), iter1;   // 迭代器
    ++iter2;
    iter1 = iter2;
    ++iter2;
    ++iter2;
    t1.erase(iter1, iter2);                  // 删除 [iter1, iter2) 区间的元素

    for(iter1 = t1.begin(); iter1 != t1.end(); ++iter1) { // 依次输出元素
        cout<<*iter1<<" ";
    }
    cout<<endl;
    // 输出为: 1 4 5 6
}

输出结果为:

linuxy@linuxy:~/STLset$ g++ -o main main.cpp
linuxy@linuxy:~/STLset$ ./main 
1 4 5 6 
linuxy@linuxy:~/STLset$

3.6 insert 方法

函数原型如下所示:

pair<iterator,bool> insert (const value_type& val);

下面来看一个例子:

#include <iostream>
#include <set>        // set 容器头文件
using namespace std;  // 没有这句,则需要使用 std::set

int main() {
    set<int>t1;             //定义 set 对象 t1

    for(int i = 1; i <= 6; ++i) {    // 插入 1 2 3 4 5 6
        t1.insert(i);
    }

    set<int>::iterator iter;         // 迭代器
    for(iter = t1.begin(); iter != t1.end(); ++iter) { // 依次输出插入的元素
        cout<<*iter<<" ";
    }
    cout<<endl;
    // 输出为: 1 2 3 4 5 6
}

输出结果为:

linuxy@linuxy:~/STLset$ g++ -o main main.cpp
linuxy@linuxy:~/STLset$ ./main 
1 2 3 4 5 6 
linuxy@linuxy:~/STLset$

3.7 find 方法

函数原型如下所示:

iterator       find (const value_type& val); // 返回指向 val 元素的迭代器

下面来看一个例子:

#include <iostream>
#include <set>        // set 容器头文件
using namespace std;  // 如果没有这句,则需要使用 std::set

int main() {
    set<int>t1;                      // 定义 set 对象 t1

    for(int i = 1; i <= 6; ++i) {    // 插入 1 2 3 4 5 6
        t1.insert(i);
    }

    set<int>::iterator iter;         // 迭代器
    iter = t1.find(5);               // 查找元素 5
    if(iter != t1.end()) {
        cout<<*iter<<endl;
    }
    // 输出为:5
}

输出结果为:

linuxy@linuxy:~/STLset$ g++ -o main main.cpp
linuxy@linuxy:~/STLset$ ./main 
5
linuxy@linuxy:~/STLset$

 四、总结

以上就是 STL set 常用的方法讲解,在遇到集合的情况下可以考虑使用 set。


🎈 欢迎小伙伴们点赞👍、收藏⭐、留言💬


好文推荐

零基础都能看懂的 STL map 详解

Git 开发必备 .gitignore 详解!【建议收藏】

一文搞懂内联函数!

【万字整理】❤️8大排序算法❤️【建议收藏】

以上是关于❤️面向初学者的 STL set 详解,一看就懂!❤️的主要内容,如果未能解决你的问题,请参考以下文章

unicode编码详解,一看就懂

一看就懂 详解redis的bitmap(面试加分项)

一看就懂 详解redis的bitmap(面试加分项)

一看就懂 详解redis的bitmap(面试加分项)

JAVA高效率 (秒级) 将千万条数据导入数据库 (已封装工具类)详解一看就懂

根据jdk1.8源码整理而得,java集合体系(继承实现关系)图解,超清晰,一看就懂,方便记忆