6-6-1:STL之map和set——set的基本使用

Posted 快乐江湖

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了6-6-1:STL之map和set——set的基本使用相关的知识,希望对你有一定的参考价值。

一:前言

(1)序列式容器和关联式容器

  • 序列式容器:前面的vector,list等均为序列式容器,特点就是其底层结构为线性结构
  • 关联式容器:与序列式容器不同,关联式容器内存储的是键值对,也即<key,value>结构,这样就一维这关联式容器检索数据的效率要远远高于序列式容器

(2)树形结构的关联式容器

STL中共有两种不同结构的关联式容器(适用于不同的应用场景):树型结构与哈希结构
其中树形结构又分为四种:mapsetmultimapmultiset这四种结构使用红黑树(平衡搜索树)作为底层结构,容器中的元素是一个有序的序列。

二:set

(1)基本介绍

  1. set是采用一定次序来存储元素的容器;
  2. 在set中,一个元素的值就代表了这个元素(value就是key,类型为T),并且每个value必须是唯一的(数学中集合的互异性);
  3. 在set内部,元素总是按照其内部比较对象(由仿函数控制)所指定的特定严格弱排(strict weak ordering)准则进行排序;
  4. set通过key访问单个元素的速度通常要比unorderer_set容器慢,但它们允许根据顺序对子集进行直接迭代
  5. set在底层使用平衡搜索树实现的(红黑树)

(2)注意

  1. map/multimap中存放是键值对<key,value>,而set中只放value(但其底层实际上是<value,value>构成的键值对)
  2. set中插入元素时,只需要插入value即可,不需要构造键值对
  3. set中的元素不可以重复,所以可以使用set进行去重
  4. 使用set的迭代器遍历set中的元素,得到有序序列
  5. set中的元素默认按照小于的方式比较(可以通过仿函数控制)
  6. set中查找某个元素的时间复杂度为log2n
  7. set中元素不允许修改

(3)set的使用

使用set需要引入头文件

#include <set>

A:set的模板参数列表

template<
	class T;set中存放的数据类型,本质为<value,value>的键值对
	class Compare=less<T>;仿函数,set中元素默认按照小于的方式比较
	class Alloc=allocator<T>;空间配置器
> class set;

B:set的常用接口

函数声明接口作用
bool empty() const判断set是否为空
size_type size() const返回set中有效元素的个数
pair<iterator,bool> insert(const value type& x)在set中插入元素x,实际插入了<x,x>的键值对,如果成功,返回<位置,true>,失败则返回<位置,false>
void erase(iterator position)删除某位置元素
size_type erase(const key_type& x),删除set中值为x的元素,返回删除元素个数
void erase(iterator first,iterator last)删除迭代器区间内的元素
void clear()将set清空
void swap(set<k,c,a>& st)交换set中的元素
iterator find(const key_type& x)const返回set中值为x的元素的位置
sizet_type count(const key_type& x) const统计set中值为x的元素的个数
  • 关于insert,以pair<iterator,bool> insert (const value_type& val);为例说明其返回值:insert会返回一个pair,其中pair中的第一个元素first是一个迭代器,它要么会指向那个新插入的元素要么会指向(插入失败)与插入元素相等的元素。第二个元素如果为true表示元素被成功插入,如果为false表示要插入的元素已经存在了。

C:set的使用举例

1:使用一数组,以一定范围构造set,数组内有重复元素

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

int main()
{
	int array[] = { 19,11,3,3,3,5,5,7,9 };
	set<int> test_set(array, array + sizeof(array) / sizeof(array[0]));
	cout << "set中有效元素个数为" << test_set.size() << endl;

	auto it = test_set.begin();
	while (it != test_set.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	cout << "set中3出现了" << test_set.count(3) << "次" << endl;
}

在这里插入图片描述

  • 可以用于构造set的数组array中的元素不仅是无序的,并且还有多个重复元素,但是在set中却是有序输出并且没有重复元素如果换成multiset,则不会去重,只会排序
    在这里插入图片描述
    2:构造一个空的set,然后不断插入
void test2()
{
	set<int> test_set;
	test_set.insert(9);
	test_set.insert(8);
	test_set.insert(8);
	test_set.insert(8);
	test_set.insert(7);
	test_set.insert(7);
	test_set.insert(6);

	for (auto e : test_set)
	{
		cout << e << " ";
	}
	cout << endl;
}

在这里插入图片描述

  1. 需要注意的是,虽然算法模块的find和set的成员函数的find效果一样的,但是效率却是千差万别,因为二叉搜索树的效率可以达到log2n
    在这里插入图片描述

以上是关于6-6-1:STL之map和set——set的基本使用的主要内容,如果未能解决你的问题,请参考以下文章

6-6:STL之map和set

C++STL之map和set的使用

C++STL之map和set的使用

带你深入理解STL之Set和Map

C++从青铜到王者第二十篇:STL之setmapmultisetmultimap的初识

Set和Map的内部结构