类似于map
/unordered_map
,set
和unordered_set
底层分别是用红黑树和哈希表实现的。
初始化方法
unordered_set<int> s1; // 不带任何参数
unordered_set<int> s2 {1, 3, 5, 7}; // 初始集合元素
set<string> s3 {"abcc", "123", "978"};
unordered_set<string> s4(s3.begin(), s3.end()); // 复制
set<string, greater<>> s5; // 默认是从小到大排序,这里变成从大到小排序
初始化的时候,可以指定初始的集合元素。set
是一个有序容器,因此可以设置元素排序的方式。
常用方法
set
与map
,unordered_set
与unordered_map
在一些命令上非常相似。
查找:
s2.find(2) != s2.end()
如果元素不存在,find
方法是会返回指向末尾的迭代器的(即.end()
)
插入:
s2.insert(2)
插入就是用insert
了。
删除:
s2.erase(2)
或者 s2.erase(s2.find(2))
,意思就是把迭代器作为参数传递进去。 该方法返回之后的迭代器。
集合其实最重要的就是查找、插入、删除三种操作了。
传入数/迭代器在set
里结果是一样的,但是multiset
里就不一样了。在multiset
里删除一个数的一次出现要使用迭代器!否则会全部删除。
遍历:
unordered_set
是无序容器,但是也支持迭代器遍历。 set
是有序容器所以遍历的时候需要注意顺序。 除此以外集合的变量与其他容器的变量没什么不同。
此外,set
还支持upper_bound
和lower_bound
函数,其使用方法跟map
的基本相同。故在此省略。
有时候我们会想用集合来保存数组,就像python的集合可以储存元组一样,但是C++不行,unordered_set
不能用来保存pair<int, int>
,但是set
可以。因为unordered_set
是基于哈希的,而C++并没有给pair
事先写好哈希方法。set
是基于比较的树结构,所以pair
里的数据结构只要都支持比较就能储存。
unordered_set<int> us {1, 2, 3, 4};
for (auto it = us.begin(); it != us.end(); it++) {
cout << *it;
}
虽然我们会用上述的方式进行迭代,但是并不代表us.end() - us.begin()
这个表达式是有效的。 有时候我们会:
set<int> s {1, 2, 3, 4};
int dist = distance(s.upper_bound(1), s.end());
使用distance
函数计算