【C++关联式容器】set

目录

set

1. 关联式容器额外的类型别名

2. Member functions

2.1 constructor、destructor、operator=

2.1.1 constructor

2.1.2 destructor

2.1.3 operator=

2.2 Iterators

2.3 Capacity

2.3.1 empty

2.3.2 size

2.3.3 max_size

2.4 Modifiers

2.4.1 insert

2.4.2 erase

2.4.3 swap

2.4.4 clear

2.4.5 emplace

2.4.6 emplace_hint

2.5 Observers

2.5.1 key_comp

2.5.2 value_comp

2.6 Operations

2.6.1 find

2.6.2 count

2.6.3 lower_bound

2.6.4 upper_bound

2.6.5 equal_range

2.7 Allocator

2.7.1 get_allocator

3. set对象的遍历方法

3.1 迭代器

3.2 范围for


set

template < class T,                        // set::key_type/value_type
           class Compare = less<T>,        // set::key_compare/value_compare
           class Alloc = allocator<T>      // set::allocator_type
           > class set;

set是按照特定顺序存储唯一元素的容器。

在set中,一个元素的值也是它的标识(值本身就是关键字,类型为T),并且每个值必须是唯一的。一旦在容器中,集合中的元素的值就不能被修改(元素总是不变的),但是它们可以被插入或从容器中移除。

在内部,set中的元素总是按照其内部比较对象(Compare类型)所指示的特定的严格的弱排序标准进行排序。

set容器通常比unordered_set容器通过键来访问单个元素要慢一些,但是它们允许根据子集的顺序来直接迭代。

set通常以二叉搜索树(准确地说,是红黑树)的形式实现。

set定义在头文件set和命名空间std中。

1. 关联式容器额外的类型别名

key_type此容器类型的关键字类型
mapped_type每个关键字关联的类型;只适用于map
value_type对于set,与key_type相同
对于map,为pair<const key_type, mapped_type>

对于set类型,key_type和value_type是一样的:set中保存的值就是关键字。在一个map中,元素是键值对。即,每个元素是一个pair对象,包含一个关键字和一个关联的值。由于我们不能改变一个元素的关键字,因此这些pair的关键字部分是const的:

set<string>::value_type vl;       // v1是一个string
set<string>::key_type v2;         // v2是一个string
map<string, int>::value_type v3;  // v3是一个pair<const string, int>
map<string, int>::key_type v4;    // v4是一个string
map<string, int>::mapped_type v5; // v5是一个int

与序列式容器一样,我们使用作用域运算符来提取一个类型的成员——例如,map<string, int>::key_type。

只有map类型(unordered_map、unordered_multimap、multimap和map)才定义了mapped_type。

2. Member functions

2.1 constructor、destructor、operator=

2.1.1 constructor

// empty (1)
explicit set(const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type());
explicit set(const allocator_type& alloc);
// range (2)
template <class InputIterator>
set(InputIterator first, InputIterator last, const key_compare& comp = key_compare(), const allocator_type& = allocator_type());
// copy (3)
set(const set& x);
set(const set& x, const allocator_type& alloc);
// move (4)
set(set&& x);
set(set&& x, const allocator_type& alloc);
// initializer list (5)
set(initializer_list<value_type> il, const key_compare& comp = key_compare(), const allocator_type& alloc = allocator_type());

创建降序排序的空set:

#include <set>
#include <iostream>
using namespace std;

struct cmp
{
	bool operator()(const int e1, const int e2) const
	{
		return e1 > e2;
	}
};

int main()
{
	set<int, cmp> st{ 4,2,2,9,6,6,6,1,7,10 };

	for (auto& e : st)
	{
		cout << e << " ";
	}
	cout << endl;
	// 10 9 7 6 4 2 1

	return 0;
}

2.1.2 destructor

~set();

2.1.3 operator=

// copy (1)
set& operator=(const set& x);
// move (2)
set& operator=(set&& x);
// initializer list (3)
set& operator=(initializer_list<value_type> il);

2.2 Iterators

// begin
iterator begin() noexcept;
const_iterator begin() const noexcept;
// end
iterator end() noexcept;
const_iterator end() const noexcept;
// rbegin
reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
// rend
reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;
// cbegin
const_iterator cbegin() const noexcept;
// cend
const_iterator cend() const noexcept;
// crbegin
const_reverse_iterator crbegin() const noexcept;
// crend
const_reverse_iterator crend() const noexcept;
函数功能

begin

&

end

begin返回一个迭代器,指向set中第一个元素

end返回一个迭代器,指向set中最后一个元素的下一个位置

rbegin

&

rend

rbegin返回一个反向迭代器,指向set中最后一个元素

rend返回一个反向迭代器,指向set中第一个元素的上一个位置

cbegin

&

cend

cbegin返回一个const迭代器,指向set中第一个元素

cend返回一个const迭代器,指向set中最后一个元素的下一个位置

crbegin

&

crend

crbegin返回一个const反向迭代器,指向set中最后一个元素

crend返回一个const反向迭代器,指向set中第一个元素的上一个位置

begin&end和rbegin&rend返回的迭代器指向:

const_iterator是一个指向const内容的迭代器。迭代器本身可以修改,但是它不能被用来修改它所指向的内容。

begin&end/rbegin&rend和cbegin&cend/crbegin&crend的不同:

  • begin&end/rbegin&rend的返回类型由对象是否是常量来决定。如果不是常量,返回iterator;如果是常量,返回const_iterator。
  • cbegin&cend/crbegin&crend的返回类型是const_iterator,不管对象本身是否是常量。

set的迭代器是const的。虽然set类型同时定义了iterator和const_iterator类型,但两种类型都只允许只读访问set中的元素。与不能改变一个map元素的关键字一样,一个set中的关键字也是const的。可以用一个set迭代器来读取元素的值,但不能修改。

#include <set>
#include <iostream>
using namespace std;

int main()
{
	int arr[10] = { 4,2,2,9,6,6,6,1,7,10 };
	set<int> st(arr, arr + 10);

	set<int>::iterator it = st.begin();
	while (it != st.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	// 1 2 4 6 7 9 10

	auto rit = st.rbegin();
	// set<int>::reverse_iterator rit = st.rbegin();
	while (rit != st.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
	// 10 9 7 6 4 2 1

	return 0;
}

2.3 Capacity

2.3.1 empty

bool empty() const noexcept;
// 检测set是否为空,是返回true,否则返回false

2.3.2 size

size_type size() const noexcept;
// 返回set中元素的个数

2.3.3 max_size

size_type max_size() const noexcept;
// 返回set能够容纳的最大元素个数

2.4 Modifiers

2.4.1 insert

// single element(1) 成功返回pair<插入位置, true>,失败返回pair<插入位置, false>
pair<iterator, bool> insert(const value_type& val);
pair<iterator, bool> insert(value_type&& val);
// with hint(2)
iterator insert(const_iterator position, const value_type& val);
iterator insert(const_iterator position, value_type&& val);
// range(3)
template <class InputIterator> void insert(InputIterator first, InputIterator last);
// initializer list(4)
void insert(initializer_list<value_type> il);

// 插入

2.4.2 erase

// (1)
iterator erase(const_iterator position);
// (2)
size_type erase(const value_type& val);
// (3)
iterator erase(const_iterator first, const_iterator last);

// 删除

2.4.3 swap

void swap(set& x);
// 交换

2.4.4 clear

void clear() noexcept;
// 清空

2.4.5 emplace

template <class... Args> pair<iterator, bool> emplace(Args&&... args);
// 对应insert,区别是:
// 当调用insert时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中
// 当调用emplace时,则是将参数传递给元素类型的构造函数,然后使用这些参数在容器管理的内存空间中直接构造元素

2.4.6 emplace_hint

template <class... Args> iterator emplace_hint(const_iterator position, Args&&... args);
// 对应insert的with hint(2),区别是:
// 当调用insert时,我们将元素类型的对象传递给它们,这些对象被拷贝到容器中
// 当调用emplace时,则是将参数传递给元素类型的构造函数,然后使用这些参数在容器管理的内存空间中直接构造元素

2.5 Observers

2.5.1 key_comp

key_compare key_comp() const;
// 返回比较对象(决定容器中元素的顺序)

2.5.2 value_comp

value_compare value_comp() const;
// 返回比较对象(决定容器中元素的顺序)

2.6 Operations

2.6.1 find

const_iterator find(const value_type& val) const;
iterator find(const value_type& val);
// 返回一个迭代器,指向第一个关键字为val的元素,若val不在容器中,则返回end迭代器

2.6.2 count

size_type count(const value_type& val) const;
// 返回关键字等于val的元素的数量
// 对于不允许重复关键字的容器,返回值永远是0或1
#include <set>
#include <iostream>
using namespace std;

int main()
{
	int arr[10] = { 4,2,2,9,6,6,6,1,7,10 };
	set<int> st(arr, arr + 10); // 1 2 4 6 7 9 10

	auto it = st.find(2);
	if (it != st.end())
	{
		cout << "2在set中" << endl;
	}
	else
	{
		cout << "2不在set中" << endl;
	}
	// 2在set中

	it = st.find(3);
	if (it != st.end())
	{
		cout << "3在set中" << endl;
	}
	else
	{
		cout << "3不在set中" << endl;
	}
	// 3不在set中

	if (st.count(7))
	{
		cout << "7在set中" << endl;
	}
	else
	{
		cout << "7不在set中" << endl;
	}
	// 7在set中

	if (st.count(5))
	{
		cout << "5在set中" << endl;
	}
	else
	{
		cout << "5不在set中" << endl;
	}
	// 5不在set中

	return 0;
}

2.6.3 lower_bound

iterator lower_bound(const value_type& val);
const_iterator lower_bound(const value_type& val) const;
// 返回一个迭代器,指向第一个关键字不小于val的元素

2.6.4 upper_bound

iterator upper_bound(const value_type& val);
const_iterator upper_bound(const value_type& val) const;
// 返回一个迭代器,指向第一个关键字大于val的元素

2.6.5 equal_range

pair<const_iterator, const_iterator> equal_range(const value_type& val) const;
pair<iterator, iterator> equal_range(const value_type& val);
// 返回一个迭代器pair,表示关键字等于val的元素的范围(左闭右开的区间)
// 若val不存在,pair的两个成员均为end迭代器
// 对于不允许重复关键字的容器,返回的范围最多只包含一个元素

2.7 Allocator

2.7.1 get_allocator

allocator_type get_allocator() const noexcept;
// 返回空间配置器

3. set对象的遍历方法

3.1 迭代器

#include <set>
#include <iostream>
using namespace std;

int main()
{
	int arr[10] = { 4,2,2,9,6,6,6,1,7,10 };
	set<int> st(arr, arr + 10);

	set<int>::iterator it = st.begin();
	while (it != st.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
	// 1 2 4 6 7 9 10

	auto rit = st.rbegin();
	// set<int>::reverse_iterator rit = st.rbegin();
	while (rit != st.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;
	// 10 9 7 6 4 2 1

	return 0;
}

3.2 范围for

#include <set>
#include <iostream>
using namespace std;

struct cmp
{
	bool operator()(const int e1, const int e2) const
	{
		return e1 > e2;
	}
};

int main()
{
	set<int, cmp> st{ 4,2,2,9,6,6,6,1,7,10 };

	for (auto& e : st)
	{
		cout << e << " ";
	}
	cout << endl;
	// 10 9 7 6 4 2 1

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值