在之前对STL的学习中,我们已经接触过STL中的部分容器,比如:vector、list、deque、forward_list(C++11)等,根据"数据在容器中的排列"特性,这些容器统称为序列式(sequence)容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。 还有一种容器是关联式(associative)容器, 关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高。 下图列出了STL中的各种容器,以及其基层与衍生层的关系:
我们先来看一下cplusplus.com - The C++ Resources Network网站对set的文档介绍:
总结一下:
注意:
set的模板参数及含义如下:
set的构造函数及其功能如下:
使用示例如下:
#include<iostream>
#include<vector>
#include<set>
using namespace std;
int main()
{
//构造一个没有元素的空容器
set<int> s1;
for (auto e : s1)
{
cout << e << " ";
}
cout << endl;
vector<int> v;
v.push_back(2);
v.push_back(5);
v.push_back(1);
v.push_back(4);
v.push_back(3);
//迭代器区间构造
set<int> s2(v.begin(), v.end());
for (auto e : s2)
{
cout << e << " ";
}
cout << endl;
//拷贝构造
set<int> s3(s2);
for (auto e : s3)
{
cout << e << " ";
}
cout << endl;
return 0;
}
运行效果如下:
set的迭代器相关函数及其功能如下:
使用示例如下:
int main()
{
vector<int> v;
v.push_back(2);
v.push_back(5);
v.push_back(1);
v.push_back(4);
v.push_back(3);
//迭代器区间构造
set<int> s(v.begin(), v.end());
//正向迭代器
set<int>::iterator it_b = s.begin(); //访问正向迭代器开始
cout << *it_b << endl;
set<int>::iterator it_e = s.end(); //访问正向迭代器结束
--it_e;
cout << *it_e << endl;
++it_e;
while (it_b != it_e)
{
cout << *it_b << " "; //使用正向迭代器遍历set
++it_b;
}
cout << endl;
//反向迭代器
set<int>::reverse_iterator rit_b = s.rbegin(); //访问反向迭代器开始
cout << *rit_b << endl;
set<int>::reverse_iterator rit_e = s.rend(); //访问反向迭代器结束
--rit_e;
cout << *rit_e << endl;
++rit_e;
while (rit_b != rit_e)
{
cout << *rit_b << " "; //使用反向迭代器遍历set
++rit_b;
}
cout << endl;
return 0;
}
运行结果如下:
set的容量相关函数及其功能如下:
使用示例如下:
int main()
{
//构造一个没有元素的空容器
set<int> s1;
cout << s1.empty() << endl;
cout << s1.size() << endl;
cout << s1.max_size() << endl;
vector<int> v;
v.push_back(2);
v.push_back(5);
v.push_back(1);
v.push_back(4);
v.push_back(3);
//迭代器区间构造
set<int> s2(v.begin(), v.end());
cout << s2.empty() << endl;
cout << s2.size() << endl;
cout << s2.max_size() << endl;
return 0;
}
运行结果如下:
set的修改相关函数及其功能如下:
函数声明 | 功能介绍 |
---|---|
pair<iterator, bool> insert(const value_type&x) | 在set中插入元素x,实际插入的是<x, x>构成的 键值对,如果插入成功,返回<该元素在set中的 位置,true>,如果插入失败,说明x在set中已经 存在,返回<x在set中的位置,false> |
void erase ( iterator position ) | 删除set中position位置上的元素 |
size_type erase ( const key_type& x ) | 删除set中值为x的元素,返回删除的元素的个数 |
void erase ( iterator first, iterator last ) | 删除set中[first, last)区间中的元素 |
void swap ( set<Key,Compare,Allocator>& st ) | 交换两个set中的元素 |
void clear ( ) | 将set中的元素清空 |
iterator find ( const key_type& x ) const | 返回set中值为x的元素的位置 |
size_type count ( const key_type& x ) const | 返回set中值为x的元素的个数 |
insert,erase,clear,find函数使用示例如下:
int main()
{
//构造一个没有元素的空容器
set<int> s1;
//插入元素
s1.insert(3);
s1.insert(1);
s1.insert(7);
s1.insert(4);
s1.insert(0);
s1.insert(8);
s1.insert(2);
s1.insert(6);
s1.insert(9);
s1.insert(5);
for (auto k : s1)
{
cout << k << " ";
}
cout << endl;
set<int>::iterator pos = s1.find(1);
//迭代器删除元素
s1.erase(pos);
for (auto k : s1)
{
cout << k << " ";
}
cout << endl;
//key值删除元素
s1.erase(3);
for (auto k : s1)
{
cout << k << " ";
}
cout << endl;
//迭代区间删除元素
s1.erase(s1.begin(), s1.find(5));
for (auto k : s1)
{
cout << k << " ";
}
cout << endl;
//清空set中的元素
s1.clear();
for (auto k : s1)
{
cout << k << " ";
}
cout << endl;
return 0;
}
运行结果如下:
swap函数使用示例如下:
int main()
{
//构造两个没有元素的空容器
set<int> s1;
set<int> s2;
//s1中插入元素
s1.insert(3);
s1.insert(1);
s1.insert(4);
s1.insert(0);
s1.insert(2);
cout << "s1 : ";
for (auto k : s1)
{
cout << k << " ";
}
cout << endl;
cout << "s2 : ";
for (auto k : s2)
{
cout << k << " ";
}
cout << endl;
//交换s1和s2的值
s1.swap(s2);
cout << "s1 : ";
for (auto k : s1)
{
cout << k << " ";
}
cout << endl;
cout << "s2 : ";
for (auto k : s2)
{
cout << k << " ";
}
cout << endl;
return 0;
}
运行结果如下:
count()函数的定义如下图:
count函数使用示例如下:
int main()
{
//构造一个没有元素的空容器
set<int> s1;
//s1中插入元素
s1.insert(3);
s1.insert(1);
s1.insert(4);
s1.insert(0);
s1.insert(2);
cout << "s1 : ";
for (auto k : s1)
{
cout << k << " ";
}
cout << endl;
cout << s1.count(2) << endl;
cout << s1.count(4) << endl;
cout << s1.count(6) << endl;
cout << s1.count(8) << endl;
return 0;
}
运行结果如下:
我们先来看一下cplusplus.com - The C++ Resources Network网站对set的文档介绍:
总结一下:
注意:
multiset的接口是和set一模一样的,区别在于具体的使用上:
首先,multiset支持插入重复的键值key, 这就意味着multiset没有set的去重作用 :
int main()
{
//构造一个没有元素的空容器set
set<int> s;
s.insert(3);
s.insert(1);
s.insert(5);
s.insert(5); //插入多个重复键值key
s.insert(5);
s.insert(4);
s.insert(5);
s.insert(2);
for (auto e : s)
{
cout << e << " ";
}
cout << endl;
//构造一个没有元素的空容器multiset
multiset<int> ms;
ms.insert(3);
ms.insert(1);
ms.insert(5);
ms.insert(5); //插入多个重复键值key
ms.insert(5);
ms.insert(4);
ms.insert(5);
ms.insert(2);
for (auto e : ms)
{
cout << e << " ";
}
cout << endl;
return 0;
}
运行结果如下:
同时,对于set模板里几乎没有什么意义的几个函数接口在multiset这里就可以得到很好的应用了,如:count,equal_range等函数:
如下代码,我们利用count函数计算multiset中5出现的次数,并利用equal_range函数将其全部删除:
int main()
{
//构造一个没有元素的空容器multiset
multiset<int> ms;
ms.insert(3);
ms.insert(1);
ms.insert(5);
ms.insert(5); //插入多个重复键值key
ms.insert(5);
ms.insert(4);
ms.insert(5);
ms.insert(2);
for (auto e : ms)
{
cout << e << " ";
}
cout << endl;
//计算5出现的次数
cout << "5出现的次数: " << ms.count(5) << endl;
//删掉所有的5
pair<multiset<int>::iterator, multiset<int>::iterator> ret = ms.equal_range(5); //这里ret的类型直接用auto也行
multiset<int>::iterator left = ret.first;
multiset<int>::iterator right = ret.second;
ms.erase(left, right);
for (auto e : ms)
{
cout << e << " ";
}
cout << endl;
return 0;
}
运行结果如下:
希望这篇关于 STL标准模板库容器set 的博客能对大家有所帮助,欢迎大佬们留言或私信与我交流.
学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!