std::set
介绍
成员函数
非成员函数
介绍
// set 模板定义
template<class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>> class set;
namespace pmr {
template< class Key, class Compare = std::less<Key> >
using set = std::set<Key, Compare, std::pmr::polymorphic_allocator<Key>>;
}
- std::set 介绍摘选自 cppreference.com 中文网 std::set 介绍
- std::set 是关联容器,含有 Key 类型对象的已排序集
- 用比较函数 比较 (Compare) 进行排序
- 搜索、移除和插入拥有对数复杂度
- set 通常以红黑树实现
- 标准库使用比较 (Compare) 概念时用等价关系确定唯一性
- 不精确地说,如果两个对象 a 与 b 相互不比较小于对方:!comp(a, b) && !comp(b, a),那么认为它们等价
成员函数
构造析构
#include <QCoreApplication>
#include <algorithm>
#include <iostream>
#include <set>
#include <string>
auto Print(const std::string &msg, const std::set<int> &lst) {
std::cout << msg << " : ";
for (const auto &pa : lst) {
std::cout << pa << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using set_int = std::set<int>;
set_int s1; //默认构造函数
Print("s1", s1);
std::less<int> cmp;
std::allocator<int> alloc;
set_int s2(cmp); //设置比较器
Print("s2", s2);
set_int s3(cmp, alloc); //设置比较器和分配器
Print("s3", s3);
set_int s4(alloc); //设置分配器
Print("s4", s4);
set_int s5{1, 1, 2, 3, 4, 5}; //初始化列表
Print("s5", s5);
set_int s6(s5.begin(), s5.end()); //迭代器初始化
Print("s6", s6);
set_int s7(s6); //拷贝构造函数
Print("s7", s7);
set_int s8(s7, alloc);
Print("s8", s8);
set_int s9(std::move(s8)); //移动构造函数
Print("s9", s9);
set_int s10(std::move(s9), alloc);
Print("s10", s10);
// 析构函数默认
return 0; // a.exec();
}
输出结果:
s1 :
s2 :
s3 :
s4 :
s5 : 1 2 3 4 5
s6 : 1 2 3 4 5
s7 : 1 2 3 4 5
s8 : 1 2 3 4 5
s9 : 1 2 3 4 5
s10 : 1 2 3 4 5
元素访问
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using set_int = std::set<int>;
set_int s1 = {3, 1, 4, 1, 5, 9, 2, 6, 5};
std::cout << "s1 : ";
std::for_each(s1.cbegin(), s1.cend(), [](int x) { std::cout << x << "\t"; });
std::cout << "\n";
return 0; // a.exec();
}
输出结果:
s1 : 1 2 3 4 5 6 9
迭代器
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using set_int = std::set<int>;
set_int s1 = {3, 1, 4, 1, 5, 9, 2, 6, 5};
set_int::iterator iter = s1.begin();//返回指向起始的迭代器
std::cout << "s1 : ";
for (; iter != s1.end(); ++iter) {
std::cout << *iter << "\t";
}
std::cout << "\n";
set_int::const_iterator citer = s1.cbegin();//返回指向起始的迭代器,const
std::cout << "s1 : ";
for (; citer != s1.cend(); ++citer) {
std::cout << *citer << "\t";
}
std::cout << "\n";
set_int::reverse_iterator riter = s1.rbegin();//返回指向起始的逆向迭代器
std::cout << "s1 : ";
for (; riter != s1.rend(); ++riter) {
std::cout << *riter << "\t";
}
std::cout << "\n";
set_int::const_reverse_iterator criter = s1.crbegin();//返回指向起始的逆向迭代器,const
std::cout << "s1 : ";
for (; criter != s1.crend(); ++criter) {
std::cout << *criter << "\t";
}
std::cout << "\n";
return 0; // a.exec();
}
输出结果:
s1 : 1 2 3 4 5 6 9
s1 : 1 2 3 4 5 6 9
s1 : 9 6 5 4 3 2 1
s1 : 9 6 5 4 3 2 1
容量
auto Print(const std::string &msg, const std::set<int> &lst) {
std::cout << msg << " : ";
for (const auto &pa : lst) {
std::cout << pa << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using set_int = std::set<int>;
set_int s1 = {3, 1, 4, 1, 5, 9, 2, 6, 5};
Print("s1", s1);
//检查容器是否为空
std::cout << std::boolalpha << "s1.empty() : " << s1.empty() << std::endl;
std::cout << "s1.size() : " << s1.size() << std::endl; //返回容纳的元素数
std::cout << "s1.max_size() : " << s1.max_size()
<< std::endl; //返回可容纳的最大元素数,和平台有关
return 0; // a.exec();
}
输出结果:
s1 : 1 2 3 4 5 6 9
s1.empty() : false
m1.size() : 7
m1.max_size() : 576460752303423487
修改器
auto Print(const std::string &msg, const std::set<int> &lst) {
std::cout << msg << " : ";
for (const auto &pa : lst) {
std::cout << pa << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using set_int = std::set<int>;
set_int s1 = {3, 1, 4, 1, 5, 9, 2, 6, 5};
Print("s1", s1);
s1.clear(); // 清除内容
Print("s1", s1);
s1.insert(10); //插入元素或结点
Print("s1", s1);
s1.emplace(20); //原位构造元素
Print("s1", s1);
s1.emplace_hint(s1.end(), 30); //使用提示原位构造元素
Print("s1", s1);
s1.erase(s1.begin()); //擦除元素
Print("s1", s1);
set_int s2;
s2.swap(s1);
Print("m1", s1);
Print("m2", s2);
return 0; // a.exec();
}
输出结果:
s1 : 1 2 3 4 5 6 9
s1 :
s1 : 10
s1 : 10 20
s1 : 10 20 30
s1 : 20 30
m1 :
m2 : 20 30
查找
auto Print(const std::string &msg, const std::set<int> &lst) {
std::cout << msg << " : ";
for (const auto &pa : lst) {
std::cout << pa << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using set_int = std::set<int>;
set_int s1 = {3, 1, 4, 1, 5, 9, 2, 6, 5};
Print("s1", s1);
std::cout << "s1.count(1) : " << s1.count(1)
<< std::endl; //返回匹配特定键的元素数量
//寻找键等于 key 的的元素,若容器中有数个拥有键 key 的元素,则可能返回任意一者
auto it = s1.find(2); //寻找带有特定键的元素
if (it == s1.end()) {
std::cout << "s1.find(2) : s1.end()" << std::endl;
} else {
std::cout << "s1.find(2) : " << *it << std::endl;
}
//返回容器中所有拥有给定关键的元素范围。范围以二个迭代器定义,一个指向首个不小于
// key 的元素,另一个指向首个大于 key 的元素。首个迭代器可以换用 lower_bound()
//获得,而第二迭代器可换用 upper_bound() 获得
std::pair<set_int::iterator, set_int::iterator> pa =
s1.equal_range(5); //返回匹配特定键的元素范围
std::cout << *pa.first << std::endl;
std::cout << *pa.second << std::endl;
set_int::iterator lit =
s1.lower_bound(2); //返回指向首个不小于给定键的元素的迭代器
std::cout << "m1.lower_bound(2) : " << *lit << std::endl;
lit = s1.upper_bound(1); //返回指向首个大于给定键的元素的迭代器
std::cout << "m1.upper_bound(1) : " << *lit << std::endl;
return 0; // a.exec();
}
输出结果:
s1 : 1 2 3 4 5 6 9
s1.count(1) : 1
s1.find(2) : 2
5
6
m1.lower_bound(2) : 2
m1.upper_bound(1) : 2
非成员函数
auto Print(const std::string &msg, const std::set<int> &lst) {
std::cout << msg << " : ";
for (const auto &pa : lst) {
std::cout << pa << "\t";
}
std::cout << "\n";
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
using set_int = std::set<int>;
set_int s1 = {3, 1, 4, 1, 5, 9, 2, 6, 5};
set_int s2 = {3, 1, 4, 1, 5, 6};
Print("s1", s1);
Print("s2", s2);
std::cout.setf(std::ios::boolalpha);
std::cout << "s1 == s2 : " << (s1 == s2) << std::endl;
std::cout << "s1 != s2 : " << (s1 != s2) << std::endl;
std::cout << "s1 > s2 : " << (s1 > s2) << std::endl;
std::cout << "s1 >= s2 : " << (s1 >= s2) << std::endl;
std::cout << "s1 < s2 : " << (s1 < s2) << std::endl;
std::cout << "s1 <= s2 : " << (s1 <= s2) << std::endl;
std::cout.unsetf(std::ios::boolalpha);
// c++20 废弃以上操作符重载,提供三路运算符 operator <=> ()
std::swap(s1, s2);
Print("s1", s1);
Print("s2", s2);
return 0; // a.exec();
}
输出结果:
s1 : 1 2 3 4 5 6 9
s2 : 1 3 4 5 6
s1 == s2 : false
s1 != s2 : true
s1 > s2 : false
s1 >= s2 : false
s1 < s2 : true
s1 <= s2 : true
s1 : 1 3 4 5 6
s2 : 1 2 3 4 5 6 9