C++ set容器:查找

本文将详细解析C++ STL中的set容器,通过代码示例讲解其核心操作和查找方法。set是一个非常有用的关联容器,它存储唯一的元素,并且元素会自动排序

1. set容器的基本特性

set容器具有以下关键特性:

  • 唯一性:所有元素都是唯一的,不允许重复
  • 自动排序:元素插入后会自动按照升序排列
  • 基于红黑树:底层实现通常为红黑树,提供高效的查找、插入和删除操作

2. 头文件与基本使用

使用set需要包含头文件:

#include <set>

声明一个set

set<int> setInt;  // 创建一个存储int类型的set

3. 插入元素

使用insert()方法添加元素:

setInt.insert(1);
setInt.insert(2);
setInt.insert(3);
setInt.insert(4);
setInt.insert(5);

插入后,元素会自动按升序排列。

4. 查找操作

4.1 find()方法

find(elem)查找指定元素,返回指向该元素的迭代器

set<int>::iterator it1 = setInt.find(4);
if (it1 != setInt.end()) {
    int elem = *it1;  // 解引用迭代器获取元素值
    cout << elem << endl;  // 输出: 4
} else {
    cout << "元素不存在" << endl;
}

重要提示:在使用find()返回的迭代器前,必须检查它是否等于end(),否则可能访问无效内存。

4.2 count()方法

count(elem)返回容器中值为elem的元素个数:

int iCount = setInt.count(3);
cout << "count(3)=" << iCount << endl;  // 输出: 1 (因为set中元素唯一)

对于set,返回值只能是0或1;对于multiset,返回值可能大于1。

5. 边界查找

5.1 lower_bound()

lower_bound(elem)返回第一个大于等于elem元素的迭代器:

set<int>::iterator it2 = setInt.lower_bound(3);
int elem2 = *it2;
cout << "lower_bound(3)=" << elem2 << endl;  // 输出: 3

5.2 upper_bound()

upper_bound(elem)返回第一个大于elem元素的迭代器:

set<int>::iterator it3 = setInt.upper_bound(3);
int elem3 = *it3;
cout << "upper_bound(3)=" << elem3 << endl;  // 输出: 4

6. equal_range()方法

equal_range(elem)返回一个pair,包含两个迭代器:

  • first:指向第一个不小于elem的元素(即lower_bound
  • second:指向第一个大于elem的元素(即upper_bound
pair<set<int>::iterator, set<int>::iterator> ii = setInt.equal_range(3);
cout << "equal_range(3) 返回迭代器的第一个值:" << *(ii.first) << endl;  // 输出: 3
cout << "equal_range(3) 返回迭代器的第二个值:" << *(ii.second) << endl; // 输出: 4

7. 注意事项

  1. 迭代器有效性:在修改set后,所有迭代器可能失效
  2. 元素唯一性:尝试插入重复元素不会改变set内容
  3. 性能:查找、插入和删除操作的时间复杂度都是O(log n)
  4. 内存:由于基于红黑树,内存开销比连续容器大

8. 实际应用场景

set非常适合以下场景:

  • 需要快速查找元素是否存在
  • 需要自动排序且元素唯一
  • 需要频繁进行集合操作(并集、交集等)

9. 完整代码回顾

#include <iostream>
#include <set>

using namespace std;

int main(void) {
    set<int> setInt;

    // 插入元素
    setInt.insert(1);
    setInt.insert(2);
    setInt.insert(3);
    setInt.insert(4);
    setInt.insert(5);

    // 查找元素
    set<int>::iterator it1 = setInt.find(8);
    if (it1 != setInt.end()) {
        int elem = *it1;
        cout << elem << endl;
    } else {
        cout << "不存在8" << endl;
    }

    // 计数
    int iCount = setInt.count(3);
    cout << "count(3)=" << iCount << endl;

    // 边界查找
    set<int>::iterator it2 = setInt.lower_bound(3);
    set<int>::iterator it3 = setInt.upper_bound(3);
    int elem2 = *it2;
    int elem3 = *it3;
    cout << "lower_bound(3)=" << elem2 << endl;
    cout << "upper_bound(3)=" << elem3 << endl;

    // 范围查找
    pair<set<int>::iterator, set<int>::iterator> ii = setInt.equal_range(3);
    cout << "equal_range(3) 返回迭代器的第一个值:" << *(ii.first) << endl;
    cout << "equal_range(3) 返回迭代器的第二个值:" << *(ii.second) << endl;

    system("pause");
    return 0;
}

set最适合需要快速查找自动排序的场景,但对于需要频繁随机访问的场景,可能需要考虑其他容器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值