当前位置 博文首页 > Linux猿:面向初学者的 STL set 详解,一看就懂!

    Linux猿:面向初学者的 STL set 详解,一看就懂!

    作者:[db:作者] 时间:2021-09-17 08:59


    ?🎈 作者: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大排序算法??【建议收藏】

    cs