STL中的find函数处理复合类型

本文介绍了如何使用STL中的find()和find_if()算法进行查找。通过示例代码展示了如何查找简单数据类型,如字符串,并解释了如何为自定义类型重载比较运算符以实现查找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如何使用STL进行查找?通用算法find()和find_if()可以做这些。就象for_each(), count(), count_if()一样,这些算法也使用iterator范围,这个范围指出一个list或任意其他容器中的一部分来处理。通常首iterator指着开始的位置,次iterator指着停止处理的地方。由次iterator指出的元素不被处理。
这是find()如何工作:

/*
 || How to find things in an STL list
 */
#include<string>
#include  <list>
#include <algorithm>

int main (void){
    list<string>  Fruit;
    list<string>::iterator FruitIterator;

    Fruit.push_back("Apple");
    Fruit.push_back("Pineapple");
    Fruit.push_back("Star Apple");

    FruitIterator = find (Fruit.begin(), Fruit.end(),"Pineapple");

    if  (FruitIterator == Fruit.end()) {
        cout << "Fruit not found in list" << endl;
     }
    else  {
        cout<< *FruitIterator <<endl;
     }
 }

输出是:

Pineapple

如果没有找到指出的对象,就会返回Fruit.end()的值,要是找到了就返回一个指着找到的对象的iterator。

以上是针对简单数据类型的查找,如string,int, char, double,float等,如果你想用一个自定义类型的数据作为查找依据该怎么做呢。

例如有这样的数据结构:

structMyType

{

  int a,b;

}

MyType* mt;

mt = new MyType;

mt->a = 1;

mt->b = 2;

list<MyType> mList;

find(mList.begin(), mList.end(), *mt);

这里find函数是不能完成查询的,最简单的原因就是它无法知道通过对比MyType的哪项完成查询。

find的查找本质上还是比较,所以只需要重载一个==操作符即可。

bool operator==(const MyType &object)
{
return object.a == a && object.b == b;
}
此外,另一种是写一个查找条件函数,利用find_if()。

假如需要根据a或b一项来查询,则需要定义个构造函数及修改下==操作符。
例如需要根据a来查询:

structMyType

{
    int a,b;
    // 定义默认构造函数
    MyType(int a)
    : a(a)
    {}
    bool operator==(const MyType &object)
    {
        return object.a == a;
    }
}

这也就可以使用find(mList.begin(), mList.end(), MyType(1));来查找是否存在a = 1的项了

### C++ STL 中 `set` 的使用方法和特性 #### 1. 基本概念 `set` 是 C++ 标准模板库(STL中的一个关联式容器,它存储的是唯一的键值集合,并自动保持有序状态。其底层实现通常基于红黑树,因此提供了高效的查找、插入和删除操作。 #### 2. 头文件与命名空间 为了使用 `set` 容器,需要包含头文件 `<set>` 并使用标准命名空间 `std`[^1]。 ```cpp #include <set> using namespace std; ``` #### 3. 创建与初始化 可以通过多种方式创建并初始化一个 `set`: - **默认构造函数** ```cpp set<int> s; // 创建一个空的整数集 ``` - **范围初始化** ```cpp vector<int> v = {4, 5, 6}; set<int> s(v.begin(), v.end()); // 将 vector 初始化到 set 中 ``` - **列表初始化** ```cpp set<int> s = {1, 2, 3, 4}; // 列表初始化 ``` 以上三种方式均会去除重复元素并按升序排列。 #### 4. 插入与删除 ##### 插入元素 可以使用 `insert()` 方法向 `set` 中添加新元素。如果元素已存在,则不会再次插入。 ```cpp s.insert(10); ``` ##### 删除元素 支持通过迭代器或具体值来删除元素: - 使用迭代器删除: ```cpp auto it = s.find(10); // 查找值为10的元素 if (it != s.end()) { s.erase(it); // 删除找到的元素 } ``` - 使用值删除: ```cpp size_t count = s.erase(10); // 返回实际删除的数量(0 或 1) ``` 当尝试删除不存在的元素时,`erase()` 不会产生错误,仅返回 0 表示未成功删除[^4]。 #### 5. 遍历 由于 `set` 自动维护顺序,遍历时可以直接按照从小到大的顺序访问所有元素: ```cpp for(auto& elem : s){ cout << elem << ' '; } ``` 或者使用迭代器: ```cpp for(set<int>::iterator it = s.begin(); it != s.end(); ++it){ cout << *it << ' '; } ``` #### 6. 查找与统计 ##### 查找特定元素 可通过 `find()` 函数定位某个值是否存在: ```cpp auto pos = s.find(10); if(pos != s.end()){ cout << "Found!" << endl; } else{ cout << "Not Found!" << endl; } ``` ##### 统计某值数量 尽管 `set` 只允许唯一值,仍可调用 `count()` 来确认某一数值的存在情况: ```cpp cout << s.count(10) << endl; // 输出要么是0(不存在),要么是1(存在) ``` #### 7. 键值对形式——`multiset` 和 `map` 除了普通的 `set`,还有其他变种用于更复杂的数据管理需求。例如,`multiset` 支持相同键多次出现;而 `map` 提供了键值映射功能[^3]。 对于键值对的需求,推荐使用 `pair` 结构配合自定义比较规则构建复合型数据结构[^2]: ```cpp struct Student { string name; int id; }; bool operator<(const Student& lhs, const Student& rhs){ return lhs.id < rhs.id; } // 应用场景实例化 set<Student> students; students.insert({"Alice", 1}); students.insert({"Bob", 2}); ``` 上述代码展示了如何定制小于运算符以便于将学生对象存入 `set` 中。 --- ### 总结 综上所述,C++ STL 中的 `set` 是一种高效且灵活的工具,适用于处理无重复且需维持自然排序的任务。无论是基本的操作还是高级的应用场景,掌握这些技巧都将极大提升程序设计能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值