[C++ STL] set使用详解
一、概述
set 容器内的元素会被自动排序,set 与 map 不同,set 中的元素即是键值又是实值,set 不允许两个元素有相同的键值。不能通过 set 的迭代器去修改 set 元素,原因是修改元素会破坏 set 组织。当对容器中的元素进行插入或者删除时,操作之前的所有迭代器在操作之后依然有效。
二、定义及初始化
使用之前必须加相应容器的头文件:
#include <set> // set属于std命名域的,因此需要通过命名限定,例如using std::set;
定义的代码如下:
set<int> a; // 定义一个int类型的集合a
// set<int> a(10); // error,未定义这种构造函数
// set<int> a(10, 1); // error,未定义这种构造函数
set<int> b(a); // 定义并用集合a初始化集合b
set<int> b(a.begin(), a.end()); // 将集合a中的所有元素作为集合b的初始值
除此之外,还可以直接使用数组来初始化向量:
int n[] = { 1, 2, 3, 4, 5 };
list<int> a(n, n + 5); // 将数组n的前5个元素作为集合a的初值
三、基本操作
3.1 容量函数
- 容器大小:
st.size();
- 容器最大容量:
st.max_size();
- 容器判空:
st.empty();
- 查找键 key 的元素个数:
st.count(key);
#include <iostream>
#include <set>
using namespace std;
int main(int argc, char* argv[])
{
set<int> st;
for (int i = 0; i<6; i++)
{
st.insert(i);
}
cout << st.size() << endl; // 输出:6
cout << st.max_size() << endl; // 输出:214748364
cout << st.count(2) << endl; // 输出:1
if (st.empty())
cout << "元素为空" << endl; // 未执行
return 0;
}
3.2 添加函数
- 在容器中插入元素:
st.insert(const T& x);
- 任意位置插入一个元素:
st.insert(iterator it, const T& x);
#include <iostream>
#include <set>
using namespace std;
int main(int argc, char* argv[])
{
set<int> st;
// 在容器中插入元素
st.insert(4);
// 任意位置插入一个元素
set<int>::iterator it = st.begin();
st.insert(it, 2);
// 遍历显示
for (it = st.begin(); it != st.end(); it++)
cout << *it << " "; // 输出:2 4
cout << endl;
return 0;
}
3.3 删除函数
- 删除容器中值为 elem 的元素:
st.pop_back(const T& elem);
- 删除it迭代器所指的元素:
st.erase(iterator it);
- 删除区间 [first,last] 之间的所有元素:
st.erase(iterator first, iterator last);
- 清空所有元素:
st.clear();
#include <iostream>
#include <set>
using namespace std;
int main(int argc, char* argv[])
{
set<int> st;
for (int i = 0; i < 8; i++)
st.insert(i);
// 删除容器中值为elem的元素
st.erase(4);
// 任意位置删除一个元素
set<int>::iterator it = st.begin();
st.erase(it);
// 删除[first,last]之间的元素
st.erase(st.begin(), ++st.begin());
// 遍历显示
for (it = st.begin(); it != st.end(); it++)
cout << *it << " "; // 输出:2 3 5 6 7
cout << endl;
// 清空所有元素
st.clear();
// 判断set是否为空
if (st.empty())
cout << "集合为空" << endl; // 输出:集合为空
return 0;
}
3.4 访问函数
- 查找键 key 是否存在,若存在,返回该键的元素的迭代器;若不存在,返回
set.end(): st.find(key);
#include <iostream>
#include <set>
using namespace std;
int main(int argc, char* argv[])
{
set<int> st;
for (int i = 0; i < 6; i++)
st.insert(i);
// 通过find(key)查找键值
set<int>::iterator it;
it = st.find(2);
cout << *it << endl; // 输出:2
return 0;
}
3.5 其他函数
- 交换两个同类型容器的元素:
swap(set&, set&);
或lst.swap(set&);
#include <iostream>
#include <set>
using namespace std;
int main(int argc, char* argv[])
{
set<int> st1;
st1.insert(1);
st1.insert(2);
st1.insert(3);
set<int> st2;
st2.insert(4);
st2.insert(5);
st2.insert(6);
// 交换两个容器的元素
st1.swap(st2);
// 遍历显示
cout << "交换后的st1: ";
set<int>::iterator it;
for (it = st1.begin(); it != st1.end(); it++)
cout << *it << " "; // 输出:4 5 6
cout << endl;
// 遍历显示
cout << "交换后的st2: ";
for (it = st2.begin(); it != st2.end(); it++)
cout << *it << " "; // 输出:1 2 3
cout << endl;
return 0;
}
四、迭代器与算法
1. 迭代器
- 开始迭代器指针:
st.begin();
- 末尾迭代器指针:
st.end();
// 指向最后一个元素的下一个位置 - 指向常量的开始迭代器指针:
st.cbegin();
// 意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。 - 指向常量的末尾迭代器指针:
lst.cend();
- 反向迭代器指针,指向最后一个元素:
st.rbegin();
- 反向迭代器指针,指向第一个元素的前一个元素:
st.rend();
- 返回最后一个 key<=keyElem 元素的迭代器:
st.lower_bound(keyElem);
- 返回第一个 key>keyElem 元素的迭代器:
st.upper_bound(keyElem);
- 返回容器中 key 与 keyElem 相等的上下限的两个迭代器,这两个迭代器被放在对组(pair)中:
st.equal_range(keyElem);
#include <iostream>
#include <set>
using namespace std;
int main(int argc, char* argv[])
{
set<int> st;
st.insert(1);
st.insert(2);
st.insert(3);
cout << *(st.begin()) << endl; // 输出:1
cout << *(--st.end()) << endl; // 输出:3
cout << *(st.cbegin()) << endl; // 输出:1
cout << *(--st.cend()) << endl; // 输出:3
cout << *(st.rbegin()) << endl; // 输出:3
cout << *(--st.rend()) << endl; // 输出:1
cout << *(st.lower_bound(2)) << endl; // 输出:2
cout << *(st.upper_bound(2)) << endl; // 输出:3
pair<set<int>::iterator, set<int>::iterator> t_pair = st.equal_range(2);
cout << *(t_pair.first) << endl; // 输出:2
cout << *(t_pair.second) << endl; // 输出:3
cout << endl;
return 0;
}
2. 算法
- 遍历元素
set<int>::iterator it;
for (it = st.begin(); it != st.end(); it++)
cout << *it << endl;
三、总结
可以看到,set 与序列式容器的用法有以下几处不同:
set 不支持 resize() 函数;
set 容器不提供下标操作符。为了通过键从 set 中获取元素,可使用 find 运算;
set 只能使用insert的两种重载函数插入,不支持 push_back() 和 push_front() 函数;
set 不支持 STL 里的 reverse 和 sort 算法;
set 能不通过迭代器,只通过元素值来删除该元素;
set 只支持默认构造函数和拷贝构造函数,没有其它重载的构造函数。
[C++ STL] set使用详解的更多相关文章
- STL bind1st bind2nd详解
STL bind1st bind2nd详解 先不要被吓到,其实这两个配接器很简单.首先,他们都在头文件<functional>中定义.其次,bind就是绑定的意思,而1st就代表fir ...
- C++ STL bitset 容器详解
C++ STL bitset 容器详解 本篇随笔讲解\(C++STL\)中\(bitset\)容器的用法及常见使用技巧. \(bitset\)容器概论 \(bitset\)容器其实就是个\(01\)串 ...
- 2.3 C++STL vector容器详解
文章目录 2.3.1 引入 2.3.2 代码实例 2.3.3 运行结果 总结 2.3.1 引入 vector 容器 动态数组 可变数组 vector容器 单口容器(尾部操作效率高) vector动态增 ...
- [GeekBand] STL 仿函数入门详解
本文参考文献::GeekBand课堂内容,授课老师:张文杰 :C++ Primer 11 中文版(第五版) page 37 :网络资料: 叶卡同学的部落格 http://www.leavesite. ...
- C++ STL之vector详解
转自http://blog.sina.com.cn/s/blog_9f1c0931010180cy.html Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作 ...
- C++ STL Binary search详解
一.解释 以前遇到二分的题目都是手动实现二分,不得不说错误比较多,关于返回值,关于区间的左闭右开等很容易出错,最近做题发现直接使用STL中的二分函数方便快捷还不会出错,不过对于没有接触过的同学,二分函 ...
- C++ STL之LIST详解A
List 容器 list是C++标准模版库(STL,Standard Template Library)中的部分内容.实际上,list容器就是一个双向链表,可以高效地进行插入删除元素. 使用list容 ...
- Qt迭代器(Java类型和STL类型)详解
迭代器为访问容器类里的数据项提供了统一的方法,Qt 有两种迭代器类:Java 类型的迭代器和 STL 类型的迭代器. 两者比较,Java 类型的迭代器更易于使用,且提供一些高级功能,而 STL 类型的 ...
- 2.2 C++STL string容器详解
文章目录 引言 2.2.1 string的特性 2.2.2 string用法理论 2.2.2.1 string构造函数 2.2.2.2 string赋值操作 2.2.2.3 string取值操作 2. ...
随机推荐
- ArrayAdapter的使用
package com.pingyijinren.test; import android.content.Context; import android.view.LayoutInflater; i ...
- Servlet开发(3)
Servlet开发 Servlet过滤器: 主要是对访问主页的用户进行过滤,通过登录系统进入的用户可以看到主页内容,在session中存在currentuser. 可以对此进行判断: package ...
- Ubuntu 16.04安装Redis
版本:4.0.2 下载地址:https://redis.io/download 离线版本:(链接: https://pan.baidu.com/s/1bpwDtOr 密码: 4cxk) 安装过程: 源 ...
- Java ThreadLocal 使用详解
ThreadLocal的官方API解释为: "该类提供了线程局部 (thread-local) 变量.这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每 ...
- linux 实现VLAN
本文将在一台linux机器上,利用linuxbridge 等技术模拟创建VLAN 环境. 首先,创建vlan interface ip link add link ens33 name ens33.8 ...
- python 交互模式 方向键乱码问题解决
python交互模式下通常用向上键来找到之前执行的命令,用左右键移动光标.这很方便.但有的时候这些键在按完后却会出现乱码. 本文只解决CentOS 6.4 下 python2.7.8 的乱码问题. 这 ...
- iOS 自己主动释放手动释放混编
当项目为手动释放时,Build Settings中,Objective-c Automatic Reference Conting 为YES 时,想要手动管理一些文件,在CompileSources中 ...
- ubuntu 中 iptables 和 ufw 的关系
我突然发现,自己平常使用的 iptables 和 ufw 到底是啥关系?平常其实iptables和ufw在配置防火墙,开启端口是,还是偶尔会使用到的. 没去思考过这两者是啥关系,哎...,这就不够好了 ...
- 013 IPv6
Router>en Router#config t Enter configuration commands, one per line. End with CNTL/Z. Router(co ...
- [Debug] Node-sass
Meet some problem when trying to install node-sass on windwos. Company has proxy settings, need to r ...