STL 中的 set关联容器
set是关联容器,跟map一样。但是跟map有区别在于在集合中,set含有元素的值Key 类型关键字。并且每个值必须是惟一的。集合中元素的值不能在容器中修改一次。set底层结构是红黑树,它同样支持高效的插入或从容器中删除它们。
set容器通过键访问单个元素通常比unordered_set容器慢,但是它们允许根据子集的顺序直接迭代。
template < class key, // set::key_type/value_type
class Compare = less<key>, // set::key_compare/value_compare
class Alloc = allocator<key> // set::allocator_type
> class set;
set 满足容器、具分配器容器、关联容器和可逆容器的要求。
模板参数
key :元素的类型。集合容器中的每个元素也由这个值惟一标识。
Compare :用比较函数进行排序。搜索、移除和插入拥有对数复杂度。
Alloc : 用于定义存储分配模型的分配器对象的类型。
迭代器
1、begin cbegin :返回指向容器第一个元素的迭代器(公开成员函数)
2、end cend :返回指向容器尾端的迭代器(公开成员函数)
3、rbegin crbegin:返回指向容器最后元素的逆向迭代器(公开成员函数)
4、rend crend:返回指向前端的逆向迭代器(公开成员函数)
begin/end
成员函数:
1、iterator begin();
2、const_iterator begin() const;
3、iterator begin() noexcept;
4、const_iterator begin() const noexcept;
5、begin 返回一个迭代器,该迭代器引用集合容器中的第一个元素。
iterator end();
6、const_iterator end() const;
7、iterator end() noexcept;
8、const_iterator end() const noexcept;
9、end 返回一个迭代器,该迭代器引用集合容器中的结束后元素。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset= {8,7,5,9,0,1,3,2,6,4};
cout <<"set:"; // set内部具有实现排序机制
for (auto it = myset.begin(); it != myset.end(); ++it)
{
cout <<" "<<*it;
}
cout << endl;
return 0;
}
rbegin/rend
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
返回指向容器中最后一个元素的反向迭代器。
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
返回一个反向迭代器,指向集合容器中第一个元素之前的理论元素。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset= {8,7,5,9,0,1,3,2,6,4};
cout <<"set:"; // set内部具有实现排序机制
// auto = set::reverse_iterator
for (auto it = myset.rbegin(); it != myset.rend(); ++it)
{
cout <<" "<<*it;
}
cout << endl;
return 0;
}
cbegin/cend
const_iterator cbegin() const noexcept;
返回指向容器中第一个元素的const_iterator。
const_iterator cend() const noexcept;
返回指向容器中结束后元素的const_iterator。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset= {8,7,5,9,0,1,3,2,6,4};
cout <<"set:"; // set内部具有实现排序机制
// auto = set::const_iterator
for (auto it = myset.cbegin(); it != myset.cend(); ++it)
{
cout <<" "<<*it;
}
cout << endl;
return 0;
}
const_reverse_iterator crbegin() const noexcept;
返回指向容器中最后一个元素的const_reverse_iterator。
const_reverse_iterator crend() const noexcept;
返回一个const_reverse_iterator,该迭代器指向理论上位于容器中第一个元素之前的元素。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset= {8,7,5,9,0,1,3,2,6,4};
cout <<"set:"; // set内部具有实现排序机制
// auto = set::const_reverse_iterator
for (auto it = myset.crbegin(); it != myset.crend(); ++it)
{
cout <<" "<<*it;
}
cout << endl;
return 0;
}
容器
1、empty:检查容器是否为空(公开成员函数)
2、size:返回容纳的元素数(公开成员函数)
3、max_size:返回可容纳的最大元素数(公开成员函数)
empty
bool empty() const;
返回集合容器是否为空,若容器为空则为 true ,否则为 false
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset= {8,7,5,9,0,1,3,2,6,4};
cout <<"before myset: "<<myset.empty()<<endl;
myset.erase(myset.begin(),myset.end());
cout <<"after myset: "<<myset.empty()<<endl;
cout << endl;
return 0;
}
size
size_type size() const noexcept;
返回集合容器中的元素数量。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset= {8,7,5,9,0,1,3,2,6,4};
cout <<"szie: "<<myset.size()<<endl;
return 0;
}
size_type max_size() const noexcept;
返回根据系统或库实现限制的容器可保有的元素最大数量。由于已知的系统或库实现限制,这是容器能够达到的最大潜在大小,但是容器并不能保证能够达到这个大小:在达到这个大小之前,它仍然可能无法分配存储空间。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset= {8,7,5,9,0,1,3,2,6,4};
cout <<"max_size: "<<myset.max_size()<<endl;
return 0;
}
修改器
1、insert:插入元素(公开成员函数)
2、erase:擦除元素(公开成员函数)
3、swap:交换内容(公开成员函数)
4、clear:清除内容(公开成员函数)
5、emplace:原位构造元素(公开成员函数)
6、emplace_hint:使用提示原位构造元素(公开成员函数)
insert
(1)
pair<iterator,bool> insert (const value_type& val);
pair<iterator,bool> insert (value_type&& val);
(2)
iterator insert (const_iterator position, const value_type& val);
iterator insert (const_iterator position, value_type&& val);
(3)
template <class InputIterator>
void insert (InputIterator first, InputIterator last);
(4)
void insert (initializer_list<value_type> il);
参数:
(1)返回由指向被插入元素(或阻止插入的元素)的迭代器和若插入发生则设为 true 的 bool 值。
(2)返回指向被插入元素,或阻止插入的元素的迭代器。
(3)指定元素范围的迭代器。范围[first,last]中的元素的副本插入容器中。
int main (int argc, char **argv)
{
set <int> myset={10,20,30,40,50};
pair<set<int>::iterator, bool> value;
set<int>::iterator it;
value = myset.insert(10);
if (value.second == false)
{
it = value.first;
}
myset.insert(it,44);
myset.insert(it,33);
set <int>sets = {1,12,3,40,30,67,34,37,21,86};
myset.insert(sets.begin(),sets.end());
cout <<"insert: ";
for ( it = myset.begin(); it != myset.end(); ++it)
{
cout <<" " <<*it;
}
cout << endl;
return 0;
}
(1)
iterator erase (const_iterator position);
(2)
size_type erase (const value_type& val);
(3)
iterator erase (const_iterator first, const_iterator last);
从容器移除指定的元素。
(1) 移除位于 position 的元素。
(2) 移除关键等于 key 的元素。
(3)从集合容器中移除单个元素或元素范围([first,last])。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset;
for (int i = 1; i <= 10; ++i)
{
myset.insert(i);
}
for (auto it = myset.begin(); it != myset.end(); ++it)
{
if (*it %2 == 1) //删除奇数
{
it = myset.erase(it);
}
else
it ++;
}
//遍历
cout <<" erase traversal: ";
for (set<int>::iterator it = myset.begin(); it != myset.end(); ++it)
{
cout <<" "<<*it;
}
cout << endl;
myset.erase(4); //删除元素4
cout <<" after number: ";
for (set<int>::iterator it = myset.begin(); it != myset.end(); ++it)
{
cout <<" "<<*it;
}
cout << endl;
return 0;
}
swap
void swap (set& other);
通过other的内容交换容器的内容,other是另一组相同类型的内容。大小可能不同。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> setA;
set <int> setB;
for (int i = 1; i <= 5; ++i)
{
setA.insert(i);
}
for (int i = 6; i <= 10; ++i)
{
setB.insert(i);
}
setA.swap(setB);
cout << " setA: ";
for (int n : setA)
{
cout <<" "<<n;
}
cout << endl;
cout << " setB: ";
for (int n : setB)
{
cout <<" "<<n;
}
cout << endl;
return 0;
}
clear
void clear() noexcept;
从容器擦除所有元素。此调用后 size() 返回零。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset;
for (int i = 1; i <= 5; ++i)
{
myset.insert(i);
}
myset.clear();
myset.insert(7);
myset.insert(9);
cout <<"value: ";
for (set<int>::iterator it = myset.begin(); it != myset.end(); ++it)
{
cout <<" "<<*it;
}
cout << endl;
return 0;
}
emplace
template <class... Args>
pair<iterator,bool> emplace (Args&&... args);
若容器中无拥有该关键的元素,则插入以给定的 args 原位构造的新元素到容器。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <string> myset;
myset.emplace("A");
myset.emplace("B");
auto value = myset.emplace("A");
if (!value.second)
cout <<"A exists in myset"<<endl;
return 0;
}
查找
1、 count:返回匹配特定键的元素数量(公开成员函数)
2、find:寻找带有特定键的元素(公开成员函数)
3、equal_range:返回匹配特定键的元素范围(公开成员函数)
4、lower_bound:返回指向首个不小于给定键的元素的迭代器(公开成员函数)
5、upper_bound:返回指向首个大于给定键的元素的迭代器(公开成员函数)
count
size_type count (const value_type& val) const;
在容器中搜索与val等价的元素,并返回匹配的数量。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset = {2,3,6,8,9};
int i;
for ( i = 0; i < 10; ++i)
{
if (myset.count(i) != 0)
{
cout <<i <<" is an element of myset"<<endl;
}
else
{
cout <<i <<" is not an element of myset"<<endl;
}
}
return 0;
}
find
const_iterator find (const value_type& val) const;
iterator find (const value_type& val);
寻找键等于 val 的的元素。 在容器中搜索与val等价的元素,如果找到,则返回一个迭代器,否则返回一个要设置::end的迭代器。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset = {2,3,6,8,9,12,34,98};
int i;
myset.erase(myset.find(9));
for (set<int>::iterator it = myset.begin(); it != myset.end(); ++it)
{
cout<<" " << *it;
}
cout << endl;
return 0;
}
lower_bound / upper_bound
(1)iterator lower_bound (const value_type& val);
(2)const_iterator lower_bound (const value_type& val) const;
(1)返回指向首个不小于 key 的元素的迭代器。
(2)返回指向首个比较不小于值 x 的元素的迭代器。
iterator upper_bound (const value_type& val);
const_iterator upper_bound (const value_type& val) const;
(1)返回指向首个大于 key 的元素的迭代器。
(2)返回指向首个比较大于值 x 的元素的迭代器。
#include
#include
#include
using namespace std;
int main (int argc, char **argv)
{
set <int> myset = {2,3,6,8,9,12,34,98};
int i;
auto itlow= myset.lower_bound(8);
auto itup= myset.upper_bound(34);
myset.erase(itlow,itup);
for (set<int>::iterator it = myset.begin(); it != myset.end(); ++it)
{
cout<<" " << *it;
}
cout << endl;
return 0;
}
扫二维码关注微信公众号,获取技术干货