• C++
  • C++ 集合 set 学习笔记

  • @ 2025-5-13 20:13:31

C++集合set教程

什么是集合(set)?

在C++里,集合(set)是一种能存储唯一元素的数据结构。它的特别之处在于,所有元素都会根据特定规则自动排序,而且每个元素只能出现一次,这就保证了集合里不会有重复元素。

为什么要使用集合?

集合的用处可多了,比如:

  • 能自动对元素进行排序。
  • 可以快速查找某个元素,效率很高。
  • 保证集合里没有重复元素。

集合的基本操作

下面是集合的一些基本操作示例:

#include <iostream>
#include <set>
using namespace std; // 使用标准命名空间,避免重复写std::

int main() {
    // 创建一个存储整数的集合
    set<int> mySet;
    
    // 插入元素
    mySet.insert(3);
    mySet.insert(1);
    mySet.insert(2);
    mySet.insert(2); // 重复元素,不会被插入
    
    // 输出集合中的元素(自动排序,输出:1 2 3)
    cout << "集合中的元素:";
    for (int num : mySet) {
        cout << num << " ";
    }
    cout << endl;
    
    // 查找元素
    if (mySet.find(2) != mySet.end()) {
        cout << "找到元素2" << endl;
    } else {
        cout << "未找到元素2" << endl;
    }
    
    // 删除元素
    mySet.erase(2);
    
    // 检查集合是否为空
    if (mySet.empty()) {
        cout << "集合为空" << endl;
    } else {
        cout << "集合不为空,大小为:" << mySet.size() << endl;
    }
    
    return 0;
}

代码解释

上面代码展示了集合的常见操作:

  1. 包含头文件:要使用集合,需要包含<set>头文件。
  2. 创建集合:使用set<int> mySet来创建一个存储整数的集合。
  3. 插入元素:通过insert()方法往集合里添加元素,集合会自动处理重复元素。
  4. 遍历集合:可以使用范围for循环来遍历集合中的元素,元素会按照从小到大的顺序排列。
  5. 查找元素:利用find()方法查找元素,如果找到了会返回该元素的迭代器,没找到则返回end()
  6. 删除元素:使用erase()方法删除指定元素。
  7. 检查集合状态:通过empty()检查集合是否为空,用size()获取集合中元素的个数。

进阶操作

除了基本操作,集合还有一些进阶用法:

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

int main() {
    set<int> mySet = {5, 3, 1, 4, 2};
    
    // 统计元素出现次数(集合中只能是0或1)
    cout << "元素3的出现次数:" << mySet.count(3) << endl;
    
    // 查找大于等于4的第一个元素
    auto it = mySet.lower_bound(4);
    if (it != mySet.end()) {
        cout << "大于等于4的第一个元素:" << *it << endl;
    }
    
    // 查找大于4的第一个元素
    it = mySet.upper_bound(4);
    if (it != mySet.end()) {
        cout << "大于4的第一个元素:" << *it << endl;
    }
    
    // 清空集合
    mySet.clear();
    cout << "清空后的集合大小:" << mySet.size() << endl;
    
    return 0;
}

进阶操作解释

进阶操作的相关说明如下:

  • count()方法:由于集合中元素唯一,该方法返回值只能是0(元素不存在)或1(元素存在)。
  • lower_bound()方法:返回一个迭代器,指向大于等于给定值的第一个元素。
  • upper_bound()方法:返回一个迭代器,指向大于给定值的第一个元素。
  • clear()方法:将集合中的所有元素删除,使集合为空。

集合的注意事项

使用集合时,有几点需要留意:

  1. 元素唯一性:集合会自动忽略重复元素,所以插入重复元素不会改变集合。
  2. 自动排序:集合中的元素会按照默认规则(升序)排序,且不能直接修改元素值,若要修改,需先删除该元素,再插入新元素。
  3. 效率问题:集合的插入、删除和查找操作效率都很高,时间复杂度为O(log n)。

总结

集合(set)是C++标准库中非常实用的一种数据结构,特别适合需要自动排序和去重的场景。通过本教程,你学会了集合的基本和进阶操作,还了解了使用集合的注意事项。希望这些内容能帮助你在编程中更好地运用集合。

4 条评论

  • @ 2025-10-21 18:50:53

    在 C++ 的 std::set(以及其他标准容器)中,rbegin()rend() 是用于获取反向迭代器(reverse iterator) 的成员函数,用于从容器末尾向开头反向遍历元素

    具体含义:

    • rbegin():返回指向容器最后一个元素的反向迭代器(可以理解为反向遍历的“第一个元素”)。
    • rend():返回指向容器第一个元素之前位置的反向迭代器(可以理解为反向遍历的“结束标志”)。

    反向迭代器的递增(++)操作实际上是向容器的开头移动,递减(--)操作则向容器的末尾移动。

    示例:

    对于 std::set<int> s = {1, 2, 3, 4, 5}(默认升序排序),使用 rbegin()rend() 反向遍历:

    #include <iostream>
    #include <set>
    
    int main() {
        std::set<int> s = {1, 2, 3, 4, 5};
        
        // 反向遍历:从最后一个元素到第一个元素
        for (auto it = s.rbegin(); it != s.rend(); ++it) {
            std::cout << *it << " "; // 输出:5 4 3 2 1
        }
        
        return 0;
    }
    

    注意:

    1. 反向迭代器的解引用(*it)获取的是当前指向的元素,与正向迭代器逻辑一致,但遍历方向相反。
    2. rend() 是反向遍历的“终止条件”,它不指向任何实际元素,类似于正向迭代器的 end()
    3. 所有支持双向迭代器的标准容器(如 std::setstd::mapstd::list 等)都支持 rbegin()rend()

    通过反向迭代器,可以方便地实现从容器末尾开始的遍历操作。

    • @ 2025-10-21 17:49:24

      在 C++ 中,std::set 是一种关联式容器,其内部元素按照特定的排序规则(默认是升序)进行存储,并且元素是唯一的。std::set 不支持下标访问,即不能通过 [] 运算符或 at() 方法来访问元素。

      这是因为 std::set 底层通常基于红黑树(一种平衡二叉搜索树)实现,元素的存储位置是由其键值和排序规则决定的,并非像 std::vectorstd::array 那样在内存中连续存储,因此无法通过下标直接定位元素。

      如果需要访问 std::set 中的元素,通常可以通过迭代器(iterator)来实现,例如:

      #include <iostream>
      #include <set>
      
      int main() {
          std::set<int> s = {1, 3, 2, 5, 4};
          
          // 使用迭代器遍历
          for (auto it = s.begin(); it != s.end(); ++it) {
              std::cout << *it << " "; // 输出:1 2 3 4 5
          }
          
          return 0;
      }
      

      如果需要访问特定位置的元素(如第一个、最后一个),可以使用 begin()end()rbegin()rend() 等方法获取迭代器后间接访问。若要查找特定值的元素,可使用 find() 方法(返回指向该元素的迭代器,若不存在则返回 end())。

      • @ 2025-5-13 20:15:38

        C++ 集合 std::set 教程

        std::set 是 C++ 标准库中的关联容器之一,它存储一组唯一且有序的元素。默认情况下,std::set 中的元素是按照升序排列的(使用 < 运算符比较),但也可以通过自定义比较函数来改变排序规则。

        📚 一、头文件

        要使用 std::set,需要包含以下头文件:

        #include <set>
        

        🧱 二、基本特性

        • 唯一性:集合中不允许重复元素。
        • 有序性:内部使用红黑树实现,默认按升序排列。
        • 插入/查找时间复杂度:O(log n)。
        • 不支持直接访问元素的位置(因为 set 是基于树结构而非连续内存)。

        ✅ 三、常用操作

        1. 声明和初始化

        #include <iostream>
        #include <set>
        
        int main() {
            std::set<int> s; // 默认升序 set
            s.insert(5);
            s.insert(3);
            s.insert(7);
            s.insert(3); // 不会插入重复值
        
            for (int x : s) {
                std::cout << x << " "; // 输出:3 5 7
            }
        }
        

        2. 插入元素:insert()

        s.insert(10);
        

        返回值是一个 pair<iterator, bool>,表示是否插入成功。

        3. 删除元素:erase()

        s.erase(5); // 删除值为 5 的元素
        

        或者根据迭代器删除:

        auto it = s.find(3);
        if (it != s.end()) {
            s.erase(it);
        }
        

        4. 查找元素:find()

        auto it = s.find(7);
        if (it != s.end()) {
            std::cout << "找到元素:" << *it << std::endl;
        } else {
            std::cout << "未找到元素" << std::endl;
        }
        

        5. 判断是否存在:count()

        if (s.count(3)) {
            std::cout << "3 存在于集合中" << std::endl;
        }
        

        由于 set 中元素唯一,返回值只能是 01

        6. 获取大小和判断是否为空

        std::cout << "集合大小:" << s.size() << std::endl;
        if (s.empty()) {
            std::cout << "集合为空" << std::endl;
        }
        

        7. 清空集合

        s.clear();
        

        🔁 四、迭代器操作

        for (auto it = s.begin(); it != s.end(); ++it) {
            std::cout << *it << " ";
        }
        

        或使用反向迭代器:

        for (auto it = s.rbegin(); it != s.rend(); ++it) {
            std::cout << *it << " ";
        }
        

        🎯 五、自定义排序规则

        你可以提供一个比较函数对象来自定义排序方式:

        struct cmp {
            bool operator()(int a, int b) const {
                return a > b; // 降序排列
            }
        };
        
        std::set<int, cmp> s;
        s.insert(5);
        s.insert(3);
        s.insert(7);
        
        for (int x : s) {
            std::cout << x << " "; // 输出:7 5 3
        }
        

        🧩 六、示例代码:综合应用

        #include <iostream>
        #include <set>
        using namespace std;
        
        int main() {
            set<int> numbers;
        
            // 插入数据
            numbers.insert({1, 3, 2, 5, 4});
            
            // 遍历输出
            cout << "集合内容:";
            for (int num : numbers) {
                cout << num << " ";
            }
            cout << endl;
        
            // 查找
            auto it = numbers.find(3);
            if (it != numbers.end()) {
                cout << "找到元素: " << *it << endl;
            }
        
            // 删除
            numbers.erase(5);
            
            // 检查是否存在
            if (!numbers.count(5)) {
                cout << "5 已被删除" << endl;
            }
        
            // 清空集合
            numbers.clear();
        
            return 0;
        }
        

        📌 七、std::multiset 简介

        如果你允许集合中存在重复元素,可以使用 std::multiset

        std::multiset<int> ms;
        ms.insert(3);
        ms.insert(3);
        ms.insert(1);
        
        // 结果:1, 3, 3
        

        其他用法与 set 类似。


        🧠 八、应用场景

        • 去重并排序的数据集
        • 快速查找是否存在某元素
        • 构建索引结构
        • 实现字典、频率统计等

        ✅ 九、总结

        操作 方法
        插入 insert()
        删除 erase()
        查找 find()
        是否存在 count()
        大小 size()
        是否为空 empty()
        清空 clear()
        自定义排序 提供比较函数

        📘 十、相关类型

        容器类型 特点
        std::set<T> 唯一、有序
        std::multiset<T> 可重复、有序
        std::unordered_set<T> 唯一、无序(哈希表实现)
        std::unordered_multiset<T> 可重复、无序
        • @ 2025-5-13 20:14:03

          C++ set 教程(通俗易懂,0基础)

          一、什么是 set

          在 C++ 中,set 是一种集合容器,属于 STL(Standard Template Library,标准模板库)的一部分。它用于存储一组唯一的元素(没有重复值),并且这些元素会自动排序

          简单来说:

          • set 中的元素是唯一的,不能重复。
          • set 中的元素默认按升序排列(从小到大)。

          二、如何使用 set

          1. 引入头文件

          #include <iostream>
          #include <set>   // 使用 set 必须包含这个头文件
          using namespace std;  // 避免每次都要写 std::
          

          三、定义一个 set

          set<int> s;  // 定义一个整型的集合
          

          也可以定义其他类型的集合:

          set<string> names;  // 字符串集合
          set<double> scores; // 双精度浮点数集合
          

          四、常用操作

          1. 插入元素 —— insert()

          s.insert(5);   // 向集合中插入数字 5
          s.insert(3);
          s.insert(5);   // 重复插入不会生效,因为 set 不允许重复元素
          

          此时集合中的元素是:3, 5

          2. 删除元素 —— erase()

          s.erase(3);  // 删除元素 3
          

          3. 查找元素 —— find()

          if (s.find(5) != s.end()) {
              cout << "找到了 5" << endl;
          } else {
              cout << "没找到 5" << endl;
          }
          
          • find() 返回的是一个迭代器(可以理解为指向元素的指针)
          • 如果没找到,返回 s.end()(表示最后一个元素之后的位置)

          4. 遍历集合 —— 使用迭代器

          for (auto it = s.begin(); it != s.end(); ++it) {
              cout << *it << " ";  // 输出每个元素
          }
          cout << endl;
          

          或者更简单的写法(C++11以上):

          for (int x : s) {
              cout << x << " ";
          }
          cout << endl;
          

          5. 判断是否为空 —— empty()

          if (s.empty()) {
              cout << "集合是空的" << endl;
          }
          

          6. 获取集合大小 —— size()

          cout << "集合中有 " << s.size() << " 个元素" << endl;
          

          7. 清空集合 —— clear()

          s.clear();  // 清空所有元素
          

          五、完整示例代码

          #include <iostream>
          #include <set>
          using namespace std;
          
          int main() {
              set<int> s;
          
              // 插入元素
              s.insert(10);
              s.insert(5);
              s.insert(8);
              s.insert(5);  // 重复插入无效
          
              // 遍历输出
              cout << "集合中的元素:";
              for (int x : s) {
                  cout << x << " ";
              }
              cout << endl;
          
              // 查找元素
              if (s.find(8) != s.end()) {
                  cout << "找到了 8" << endl;
              }
          
              // 删除元素
              s.erase(5);
          
              // 再次遍历
              cout << "删除后集合中的元素:";
              for (int x : s) {
                  cout << x << " ";
              }
              cout << endl;
          
              // 其他操作
              cout << "集合大小:" << s.size() << endl;
              cout << "是否为空:" << (s.empty() ? "是" : "否") << endl;
          
              return 0;
          }
          

          输出结果:

          集合中的元素:5 8 10 
          找到了 8
          删除后集合中的元素:8 10 
          集合大小:2
          是否为空:否
          

          六、小结

          操作 方法
          插入元素 insert()
          删除元素 erase()
          查找元素 find()
          遍历元素 迭代器或范围 for 循环
          判断空 empty()
          获取大小 size()
          清空集合 clear()

          七、进阶知识(可选)

          1. 降序排列的 set

          默认是升序排列,可以通过指定比较函数来改变顺序:

          set<int, greater<int>> s;  // 从大到小排序
          

          2. 自定义类型放入 set

          比如你想把结构体或类对象放到 set 中,需要自己提供比较方式(重载 < 运算符或自定义比较函数)。


          八、练习题(建议动手试试)

          1. 创建一个字符串集合,添加几个名字(如 "Tom", "Jerry", "Alice"),然后输出所有内容。
          2. 输入一个数组,将其中的元素插入到 set 中,输出去重并排序后的结果。
          3. 编写程序判断用户输入的数字是否已经存在于集合中。

          如果你还有任何疑问,欢迎继续提问!😊

          • 1