为什么使用 set
set 是 C++ STL 内封装实现的平衡二叉树,效率较高,提供的成员函数(包括一些常用的操作:插入、删除和查找等)符合程序员的编程习惯,使用起来很方便。
为什么 set 的效率高
set 容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点。因此在插入和删除元素时只是指针移动的操作,而不需要移动内存。
注意事项
set 可以理解为数学上的集合,每个元素最多只出现一次。
自定义类型也可以使用 set,只需定义“小于”运算符即可。
常用操作
基本查询:
begin()
返回 set 容器的第一个元素(迭代器)
end()
返回 set 容器的最后一个元素(迭代器)
empty()
判断 set 容器是否为空
size()
返回当前 set 容器中的元素个数
count(x)
判断 set 容器中是否有键值为 x 的元素
插入删除:
insert(x)
向 set 容器中插入键值为 x 的元素
erase(it)
删除迭代器 it 指向的元素
erase(first,second)
删除迭代器 first 和 second 之间的元素
erase(x)
删除键值为 x 的元素
clear()
删除 set 容器中的所有的元素
二分查找:
lower_bound(x)
返回第一个大于等于 x 的迭代器
upper_bound(x)
返回最后一个大于等于x 的迭代器
使用样例
#include <iostream>
#include <set>
int main ()
{
std::set<int> myset;
myset.insert (100);
myset.insert (200);
myset.insert (300);
std::cout << "myset contains:";
for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it) //迭代器可以理解为“类似指针的东西”
std::cout << ' ' << *it;
std::cout << '\n';
myset.clear();
myset.insert (1101);
myset.insert (2202);
std::cout << "myset contains:";
for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
输出结果:
myset contains: 100 200 300
myset contains: 1101 2202
例题:UVA10815
题目大意:输入一个文本,找出所有不同的单词(连续的字母序列),按字典序从小到大输出。单词不区分大小写。
分析:显然可以将单词插入一个 set 中,利用 set 中元素已从小到大排序这一性质,用一个 for 循环即可从小到大遍历输出所有元素。但本题的输入比较麻烦,如果不想手写输入,则可以使用速度较慢的 sstream,编写起来比较简单。
参考代码:
#include <algorithm>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <set>
#include <sstream>
#include <string>
using namespace std;
typedef set <string> setstr;
setstr dict;
string str, temp;
int main(void) {
dict.clear(); //初始化清空容器
while (cin >> str) {
int len = str.size();
for (int i = 0; i < len; i++)
str[i] = isalpha(str[i]) ? tolower(str[i]) : ' ';
//一方面将字母标准化统一变成小写,另一方面将符号统一变成空格方便sstream处理
stringstream ss;
ss << str;
while (ss >> temp) dict.insert(temp); //重复插入不会造成问题
}
for (setstr::iterator it = dict.begin(); it != dict.end(); ++it)
cout << *it << endl; //利用迭代器遍历输出
return 0;
}
参考资料
- set - C++ Reference
- STL中的set容器的一点总结
- 刘汝佳《算法竞赛入门经典(第二版)》清华大学出版社