系列文章目录
[温习C/C++]0x00-STL标准模板库概述
[温习C/C++]0x01-STL泛型算法-持续更新长文版
[温习C/C++]0x03-sort排序
[温习C/C++]0x04 C++刷题基础编码技巧
[温习C/C++]0x05 C++刷题技巧—set自定义排序及查找
更新日志
| 日期 | 变更内容 |
|---|---|
| 2025-09-07 | 完成初稿 |
目标
在set<Student, MyCompare>集合中, 在按 “年龄不同时按身高升序、年龄相同时按姓名升序” 规则排序的学生集合中,查找并输出第一个不小于(年龄 4、身高 120、姓名 “Abc”)的学生元素。
重载()
#include <iostream>
#include <set>
#include <string>
using namespace std;
struct Student {
int age;
int height;
string name;
Student(int a, int h, string n): age(a), height(h), name(n) {}
};
class MyCompare {
public:
bool operator()(const Student& s1, const Student& s2) const { // 这里重要,必须结尾声明成const
if (s1.age != s2.age) { // 年龄不等的时候
return s1.height < s2.height; // 身高升序
}
return s1.name.compare(s2.name); // 名字升序
}
};
int main(int argc, char **argv) {
set<Student, MyCompare> stuSet;
stuSet.insert(Student(3, 125, "Orage"));
stuSet.insert(Student(3, 105, "Apple"));
stuSet.insert(Student(4, 115, "Lemon"));
stuSet.emplace(4, 106, "Grape");
auto iter = stuSet.lower_bound(Student(4, 120, "Abc"));
if (iter != stuSet.end()) {
cout << iter->age << " " << iter->height << " " << iter->name << endl;
}
return 0;
}
- 排序后结果

这段代码的核心功能是在一个自定义排序规则的set容器中,查找第一个不小于(即大于或等于)指定学生对象的元素,具体分析如下:
解析
Student结构体:表示学生对象,包含age(年龄)、height(身高)、name(姓名)三个属性。
MyCompare比较器:定义了set中元素的排序规则:
若两个学生的age(年龄)不同,则按height(身高)升序排列(s1.height < s2.height);
若age相同,则按name(姓名)升序排列(通过string::compare实现,本质是字典序)。
set<Student, MyCompare> stuSet:一个按MyCompare规则排序的集合,存储学生对象。
查找逻辑
代码中通过stuSet.lower_bound(Student(4, 120, "Abc"))进行查找:
lower_bound是set的成员函数,功能是返回集合中第一个不小于(即大于或等于)目标值的元素的迭代器(“不小于” 的判断依据是集合的比较器MyCompare)。
目标值是临时构造的学生对象Student(4, 120, "Abc")(年龄 4、身高 120、姓名 “Abc”)。
查找结果分析
结合集合中的元素和排序规则:
集合中的 4 个学生按MyCompare排序后,顺序为:
(3, 105, "Apple")(年龄 3,身高 105)
(3, 125, "Orage")(年龄 3,身高 125)
(4, 105, "Grape")(年龄 4,身高 105)
(4, 115, "Lemon")(年龄 4,身高 115)
按MyCompare规则判断 “是否不小于目标(4, 120, “Abc”)”:
前两个元素年龄为 3(与目标年龄 4 不同),比较身高:
第 1 个元素身高 105 < 120 → 小于目标;
第 2 个元素身高 125 > 120 → 不小于目标(满足条件)。
因此,lower_bound返回的是第 2 个元素(3, 125, "Orage")的迭代器,最终输出该元素的信息。
重载<
#include <iostream>
#include <set>
#include <string>
using namespace std;
struct Student {
int age;
int height;
string name;
Student(int a, int h, string n): age(a), height(h), name(n) {}
bool operator < (const Student& other) const { // 这里重要,必须结尾声明成const
if (age != other.age) { // 年龄不等的时候
return height < other.height; // 身高升序
}
return name.compare(other.name); // 名字升序
}
};
int main(int argc, char **argv) {
set<Student> stuSet;
stuSet.insert(Student(3, 125, "Orage"));
stuSet.insert(Student(3, 105, "Apple"));
stuSet.insert(Student(4, 115, "Lemon"));
stuSet.emplace(4, 106, "Grape");
auto iter = stuSet.lower_bound(Student(4, 120, "Abc"));
if (iter != stuSet.end()) {
cout << iter->age << " " << iter->height << " " << iter->name << endl;
}
return 0;
}
insert 和 emplace 的使用
emplace对应insert, emplace_back对应于push_back。
但insert和push_back是直接将对象拷贝至容器当中,而emplace和emplace_back是先调用存储对象构造函数,在内存中生成对象,然后拷贝至容器中。

345

被折叠的 条评论
为什么被折叠?



