C++ 标准模板库(STL)——set的使用

目录

一、描述

二、创建和初始化

三、插入元素

四、删除元素

五、查找元素

六、遍历元素

七、大小和空判断

八、迭代器

九、自定义比较函数

十、其他函数

十一、注意事项


一、描述

std::set 是 C++ STL 中的一个关联容器,用于存储唯一的元素,并且这些元素是按照某种顺序排列的(默认情况下是升序)。std::set 内部通常实现为红黑树,因此插入、删除和查找操作的时间复杂度都是 O(log n)。

基本特性

  • 唯一性:每个元素只能出现一次。
  • 有序性:元素按某种顺序排列,默认为升序。
  • 迭代器:提供双向迭代器,可以从前向后或从后向前遍历元素。

二、创建和初始化

set 是一个模板类,定义在 <set> 头文件中。它的元素是按严格弱序(即使用 < 运算符)排序的。set 默认使用 std::less<T> 作为比较函数对象,但你可以通过传递自定义的比较函数对象来定义排序方式

如:std::set<int, std::greater<int>> mySet; // 降序排列

#include <set>
#include <iostream>

int main()
{
    std::set<int> mySet; // 创建一个空的 set

    // 初始化 set
    std::set<int> anotherSet = {1, 3, 5, 7, 9};

    // 输出 set 中的元素
    for (int elem : anotherSet)
    {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

三、插入元素

使用 insert 成员函数插入元素。如果元素已经存在,则插入操作不会改变集合

mySet.insert(10);

mySet.insert(20);

mySet.insert(10); // 重复插入,集合不会改变

#include <set>
#include <iostream>

int main()
{
    std::set<int> mySet;

    // 插入元素
    mySet.insert(10);
    mySet.insert(20);
    mySet.insert(30);

    // 插入重复元素(不会插入)
    mySet.insert(10);

    // 输出 set 中的元素
    for (int elem : mySet)
    {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

四、删除元素

使用 erase 成员函数删除元素。可以通过值或迭代器删除

#include <set>
#include <iostream>

int main()
{
    std::set<int> mySet = {10, 20, 30, 40, 50};

    // 删除指定元素
    mySet.erase(30);

    // 删除范围内的元素
    mySet.erase(mySet.begin(), mySet.find(40));

    // 输出 set 中的元素
    for (int elem : mySet)
    {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

五、查找元素

使用 find 成员函数查找元素。如果找到,返回指向该元素的迭代器;否则,返回 end()。

#include <set>
#include <iostream>

int main()
{
    std::set<int> mySet = {10, 20, 30, 40, 50};

    // 查找元素
    auto it = mySet.find(30);
    if (it != mySet.end())
    {
        std::cout << "Element found: " << *it << std::endl;
    }
    else
    {
        std::cout << "Element not found" << std::endl;
    }

    return 0;
}

六、遍历元素

由于 set 中的元素是排序的,你可以使用迭代器来访问元素。set 提供的迭代器是双向迭代器。

也可以使用新特性进行遍历

for (const auto& data : mySet)
{
        cout << data << endl;
}

#include <set>
#include <iostream>

int main()
{
    std::set<int> mySet = {10, 20, 30, 40, 50};

    // 使用范围 for 循环遍历
    for (int elem : mySet)
    {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // 使用迭代器遍历
    for (auto it = mySet.begin(); it != mySet.end(); ++it)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    return 0;
}

七、大小和空判断

使用 size 和 empty 成员函数

  • size():返回 set 中的元素数量。
  • empty():检查 set 是否为空。
  • clear():清除 set 中的所有元素。
  • count():检查 set 中是否存在某个元素(返回 0 或 1)。
std::cout << "Size: " << mySet.size() << std::endl;
if (mySet.empty())
{
    std::cout << "Set is empty" << std::endl;
}

八、迭代器

set 提供了 begin、end、rbegin 和 rend 成员函数来返回迭代器。

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

九、自定义比较函数

std::set 可以接受自定义的比较函数,以便按照特定的顺序存储元素。

#include <set>
#include <iostream>
#include <string>

struct CompareLength {
    bool operator()(const std::string& a, const std::string& b) const
    {
        return a.length() < b.length();
    }
};

int main()
{
    std::set<std::string, CompareLength> mySet;

    mySet.insert("short");
    mySet.insert("longer");
    mySet.insert("medium");

    // 输出 set 中的元素
    for (const auto& elem : mySet)
    {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    return 0;
}

十、其他函数

  • clear(): 清除所有元素。
  • count(const T& value) const: 返回值为 value 的元素的个数(对于 set 来说,最多为 1)。
  • lower_bound(const T& value) const: 返回指向第一个不小于 value 的元素的迭代器。
  • upper_bound(const T& value) const: 返回指向第一个大于 value 的元素的迭代器。
  • equal_range(const T& value) const: 返回一个 pair,包含 lower_bound 和 upper_bound 的结果。

十一、注意事项

  • 唯一性:set 中的元素是唯一的,如果尝试插入一个已存在的元素,插入操作将失败。
  • 排序:set 中的元素是按顺序存储的,默认是升序。你可以通过传递自定义的比较函数对象来改变排序方式。
  • 迭代器失效:在 set 中插入或删除元素时,指向这些元素的迭代器会失效。因此,不要在插入或删除元素后继续使用旧的迭代器。

示例代码
以下是一个完整的示例代码,展示了如何使用 set:

#include <iostream>
#include <set>

int main()
{
    std::set<int> mySet;

    // 插入元素
    mySet.insert(5);
    mySet.insert(2);
    mySet.insert(8);
    mySet.insert(2); // 重复插入

    // 访问元素
    std::cout << "Set elements: ";
    for (auto it = mySet.begin(); it != mySet.end(); ++it)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 查找元素
    auto it = mySet.find(8);
    if (it != mySet.end())
    {
        std::cout << "Found: " << *it << std::endl;
    }

    // 删除元素
    mySet.erase(2);
    std::cout << "After erase 2: ";
    for (auto it = mySet.begin(); it != mySet.end(); ++it)
    {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 检查大小和是否为空
    std::cout << "Size: " << mySet.size() << std::endl;
    if (mySet.empty())
    {
        std::cout << "Set is empty" << std::endl;
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值