C++ set和map使用

set和map

  • 1.关联式容器
  • [2. 键值对](#2. 键值对)
  • [3. set](#3. set)
    • [3.1 介绍](#3.1 介绍)
    • [3.2 简单使用](#3.2 简单使用)
  • 4.multiset
  • 5.map
    • [5.1 介绍](#5.1 介绍)
    • [5.2 简单使用](#5.2 简单使用)
  • [6. multimap](#6. multimap)

1.关联式容器

关联式容器是一种STL容器,用于存储键-值对。它们提供了一种通过键来快速查找值的机制。STL总共实现了两种不同结构的管理式容器:树型结构(map、set、multimap、multiset)与哈希结构 。在关联式容器中,里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高.

2. 键值对

概念:用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值,value表示与key对应的信息。

STL中键值对结构的定义:

cpp 复制代码
template<class T1,class T2>
struct pair
{
	typedef T1 first_type; 
	typedef T2 second_type;
	
	T1 first;
	T2 second;
	pair():first(T1()),second(T2())
	{}
	pair(const T1& a,const T2& b):first(a),second(b)
	{}
};

3. set

3.1 介绍

  1. set的底层是二叉搜索树(红黑树)。
  2. set中的数据是有序去重的。
  3. set中的数据是被const 修饰的,所以不能修改,但是可以插入和删除。
  4. set默认的排序是按照从小到大的。如果想要按照自己的想法排序,需要自己写一个仿函数。
  5. 和map不同的是,set底层的键值对不是<key,value>而是<value,value>。
  6. set容器查找效率很高,时间复杂度为O(log2 N)

3.2 简单使用

  1. begin()    返回set容器的第一个元素
  2. end()      返回set容器的最后一个元素
  3. clear()    删除set容器中的所有的元素
  4. empty()    判断set容器是否为空
  5. insert()    插入一个元素
  6. size()      set容器内元素个数
  7. clear()    清空容器
cpp 复制代码
int main()
{
	//去重加排序
	set<int> s;
	s.insert(10);
	s.insert(10);
	s.insert(1);
	s.insert(20);
	s.insert(20);
	s.insert(8);
	s.insert(5);
	cout << s.size() << endl;
	set<int>::iterator it = s.begin();
	while (it != s.end())
		cout << *it++ << " ";
	cout << endl;
	s.clear();
	cout << s.size();
	return 0;
}
  1. count()
    用来查找set中某个某个键值出现的次数。这个函数在set并不是很实用,因为一个键值在set只可能出现0或1次,这样就变成了判断某一键值是否在set出现过了
cpp 复制代码
void test2()
{
	set<int> s;
	s.insert(10);
	s.insert(10);
	s.insert(1);
	s.insert(20);
	s.insert(20);
	s.insert(8);
	s.insert(5);
	cout << "10的个数:" << s.count(10) << endl;
	cout << "5的个数:" << s.count(5) << endl;
	cout << "100的个数:" << s.count(100) << endl;
	if (s.count(10))
	{
		//do...
	}
}

erase(iterator)       删除迭代器iterator指向的值

erase(first,second)       删除迭代器first和second之间的值

erase(key_value)       删除键值key_value的值
注:前两个必须保证迭代器有效,不然程序会崩溃,最后一个,不管值存不存在都可以

cpp 复制代码
void test3()
{
	set<int> s;
	set<int>::const_iterator iter;
	set<int>::iterator first;
	set<int>::iterator second;
	for (int i = 1; i <= 10; ++i)
		{
		    s.insert(i);
		}
	//第一种删除
		s.erase(s.begin());
	//第二种删除
	first = s.begin();
	second = s.begin();
	second++;
	second++;
	s.erase(first, second);
	//第三种删除
		s.erase(8);
	cout << "删除后 set 中元素是 :";
	for (iter = s.begin(); iter != s.end(); ++iter)
	{
		cout << *iter << " ";
	}
	cout << endl;
	
}

lower_bound(key_value)       返回第一个大于等于key_value的迭代器

upper_bound(key_value)      返回最后一个大于key_value的迭代器

这两个函数也可以用于于删除一个区间的数据。

cpp 复制代码
void test4()
{
	set<int> s;
	s.insert(5);
	s.insert(1);
	s.insert(6);
	s.insert(3);
	s.insert(4);

	auto start = s.lower_bound(3);  // >=val
	cout << *start << endl;

	auto finish = s.upper_bound(5);  // >val
	cout << *finish << endl;
	

	while (start != finish)
	{
		cout << *start << " ";
		++start;
	}
	cout << endl;
}

4.multiset

该容器允许键值重复,其他的使用和set差不多。这样count()的作用就显现出来了。还有一个不同的是find()返回的是中序遍历的第一个。

5.map

5.1 介绍

  1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元 素。
  2. 在map中,键值key通常用于排序和唯一的标识元素,而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名称为pair: typedef pair<const key, T> value_type;
  3. 在内部,map中的元素总是按照键值key进行比较排序(默认升序)的。
  4. 和set一样key不允许修改,但是key所关联的value可以修改。
  5. map支持下标访问符(set不支持),即在[]中放入key,就可以找到与key对应的value。
  6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))

5.2 简单使用

map的使用和set的使用基本是差不多,但是map的[]运算符使用起来还是很方便的,下面就简单介绍几种。

  1. 插入数据的几种方法:
cpp 复制代码
//1.直接insert pair
map<string,int> m;
m.insert(pair<string,int>("apple",1));
cpp 复制代码
//2. 直接insert value_type 其实本质和第一种方式一样
map<string,int> m;
m.insert(map<string,int>::value_type("apple",1));
cpp 复制代码
//3. 使用[]运算符,这种是最简便的方法
map<string,int> m;
m["apple"] = 1;
  1. 修改数据
cpp 复制代码
//如果数据原本不存在,就相当于插入操作
map<string,int> m;
m["apple"]++;
  1. 查找数据
cpp 复制代码
map<string,int> m;
if(m["apple"])
cout << m[apple] << endl;

6. multimap

和map不同的是,multimap允许有重复的key值,但这同时也导致了multimap没有[]这个运算符,因为会导致二义性。

相关推荐
魔道不误砍柴功几秒前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_234几秒前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨3 分钟前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
UestcXiye1 小时前
《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
c++·计算机网络·ip·tcp
测开小菜鸟2 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
P.H. Infinity3 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天3 小时前
java的threadlocal为何内存泄漏
java
霁月风3 小时前
设计模式——适配器模式
c++·适配器模式
caridle3 小时前
教程:使用 InterBase Express 访问数据库(五):TIBTransaction
java·数据库·express
^velpro^3 小时前
数据库连接池的创建
java·开发语言·数据库