文章目录
- 一、设置 set 集合容器的排序规则
- 1、默认的 set 集合容器 - 从小到大排列
- 2、设置 set 集合容器从大到小排列
- 二、使用仿函数自定义 set 集合容器 排序规则
- 1、仿函数概念
- 2、使用仿函数实现 set 集合容器排序规则
一、设置 set 集合容器的排序规则
1、默认的 set 集合容器 - 从小到大排列
set 集合容器 底层由 红黑二叉树 数据结构实现 , 默认元素从小到大排序 ;
使用 set<int, less<int>>
和 set<int>
定义的集合容器是一样的 ;
less
是一个结构体 , 结构体中定义了一个 operator()
函数 , 这是一个比较函数 , 对两个值进行了比较 , 该结构体原型如下 :
// STRUCT TEMPLATE less
template <class _Ty = void>
struct less {
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty _FIRST_ARGUMENT_TYPE_NAME;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty _SECOND_ARGUMENT_TYPE_NAME;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool _RESULT_TYPE_NAME;
_NODISCARD constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const {
return _Left < _Right;
}
};
下面的 2 个集合容器 , 一个是默认的集合容器 , 一个是手动定义的 元素从小到大排列的容器 ;
set<int> se{ 9, 5, 2, 7 };
set<int, less<int>> se2{ 9, 5, 2, 7 };
代码示例 :
#include "iostream"
using namespace std;
#include "set"
// 声明遍历打印 set 集合容器的函数
void printS(set<int>& se);
int main() {
// set 集合容器
// 初始化列表中的顺序会自动排序
set<int> se{ 9, 5, 2, 7 };
set<int, less<int>> se2{ 9, 5, 2, 7 };
// 打印 set 集合容器
printS(se);
printS(se2);
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
// 遍历打印 set 集合容器元素
void printS(set<int>& se) {
// 遍历 set 集合容器
for (set<int>::iterator it = se.begin(); it != se.end(); it++)
{
cout << *it << " ";
}
// 回车换行
cout << endl;
}
执行结果 :
2 5 7 9
2 5 7 9
Press any key to continue . . .
2、设置 set 集合容器从大到小排列
在 C++ 语言的 STL 标准模板库 中 , set 容器默认是按照升序 从小到大 排序的 ;
如果要设置自定义排序规则 , 可以通过传递一个比较函数或函数对象来指定排序方式 , 该比较函数设置在 <> 中 , 使用逗号与元素类型隔开 ;
使用如下方式 , 定义的 set 集合 , 其元素的排列是从大道小进行排列的 ;
set<int, greater<int>> se;
上述 greater 结构体原型如下 :
// STRUCT TEMPLATE greater
template <class _Ty = void>
struct greater {
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty _FIRST_ARGUMENT_TYPE_NAME;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef _Ty _SECOND_ARGUMENT_TYPE_NAME;
_CXX17_DEPRECATE_ADAPTOR_TYPEDEFS typedef bool _RESULT_TYPE_NAME;
_NODISCARD constexpr bool operator()(const _Ty& _Left, const _Ty& _Right) const {
return _Left > _Right;
}
};
完整代码示例 :
#include "iostream"
using namespace std;
#include "set"
// 声明遍历打印 set 集合容器的函数
void printS(set<int>& se);
void printS2(set<int, greater<int>>& se);
int main() {
// set 集合容器
// 初始化列表中的顺序会自动排序
set<int> se{ 9, 5, 2, 7 };
set<int, less<int>> se2{ 9, 5, 2, 7 };
set<int, greater<int>> se3{ 9, 5, 2, 7 };
// 打印 set 集合容器
printS(se);
printS(se2);
printS2(se3);
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
// 遍历打印 set 集合容器元素
void printS(set<int>& se) {
// 遍历 set 集合容器
for (set<int>::iterator it = se.begin(); it != se.end(); it++)
{
cout << *it << " ";
}
// 回车换行
cout << endl;
}
// 遍历打印 set 集合容器元素
void printS2(set<int, greater<int>>& se) {
// 遍历 set 集合容器
for (set<int>::iterator it = se.begin(); it != se.end(); it++)
{
cout << *it << " ";
}
// 回车换行
cout << endl;
}
执行结果 :
2 5 7 9
2 5 7 9
9 7 5 2
Press any key to continue . . .
二、使用仿函数自定义 set 集合容器 排序规则
1、仿函数概念
使用 仿函数 为 set 集合容器 定义 元素排序规则 ;
仿函数 functor 是一个在许多编程语言中都存在的概念 , 它通常指一个对象 , 该对象能像函数那样被调用 ; 具体来说 , 仿函数是一个类 , 该类重载了operator() 函数 , 使其可以像函数那样被调用 , 这种类通常被称为仿函数类或函数对象 ;
在 C++ 语言中 , 仿函数可以用来实现高阶函数 , 即接受函数作为参数或返回函数的函数 ; 例如 : C++ 标准库中的 std::less / std::plus 等都是仿函数类 ;
2、使用仿函数实现 set 集合容器排序规则
在下面的代码中 , 定义了仿函数类 IntCompare , 重载了operator() 函数 , 以便该仿函数可以像函数那样被调用 ;
下面的 仿函数 实现了 int 类型元素的降序排列 ;
struct IntCompare {
bool operator()(const int& a, const int& b) const volatile {
return (a < b); // 降序排序
}
};
在创建 set 集合容器时 , 将仿函数 传入类型中 , 即可在排序时自动调用仿函数进行 元素排序 ;
set<int, IntCompare> se;
代码示例 :
#define _CRT_SECURE_NO_WARNINGS
#include "iostream"
using namespace std;
#include "set"
struct IntCompare {
bool operator()(const int& a, const int& b) const volatile {
return (a < b); // 降序排序
}
};
int main() {
// set 集合容器
// 初始化列表中的顺序会自动排序
set<int, IntCompare> se;
// 插入数据
se.insert(9);
se.insert(5);
se.insert(2);
se.insert(7);
// 遍历 set 集合容器
for (set<int, IntCompare>::iterator it = se.begin(); it != se.end(); it++)
{
cout << *it << " ";
}
// 回车换行
cout << endl;
// 控制台暂停 , 按任意键继续向后执行
system("pause");
return 0;
};
执行结果 :
2 5 7 9
Press any key to continue . . .