map和set(一)——关联式容器的常用接口使用及区别

一、关联式容器

在初阶阶段,我们已经接触过STL中的部分容器,比如:vector、list、deque、forward_list(C++11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面 、存储的是元素本身。

那什么是关联式容器?它与序列式容器有什么区别? 关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结构的键值对,在数据检索时比序列式容器效率更高。

二、键值对

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

上次我们二叉搜索树讲到kv模型中key-val就是一个键值对,

在举个例子:如果键值对对应的是名字与拼音,以map的使用为例

#include<iostream>
#include<map>

using namespace std;

int main()
{
	map<string, string> dirt;
	dirt.insert(pair<string, string>("小明","xiaoming"));
	dirt.insert(make_pair("小李", "xiaoli"));
	pair<string, string> kv("张三", "zhangsan");
	dirt.insert(kv);

	return 0;
}

 三、set的使用

3.1set的介绍

  1. set是按照一定次序存储元素的容器
  2.  在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
  3. 在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行 排序。
  4. set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对 子集进行直接迭代。
  5. set在底层是用二叉搜索树(红黑树)实现的。

 

 T是set中存放元素的类型,底层存储用<value,value>的键值对

Compare:set中元素默认按照小于来比较

Alloc:set中元素空间的管理方式,使用STL提供的空间配置器管理

 3.2set的构造

跟大部分的容器类似,这些我就不细讲了

函数声明        功能介绍
set (const Compare& comp = Compare(), const Allocator& = Allocator() );构造空的set
set (InputIterator first, InputIterator last, const Compare& comp = Compare(), const Allocator& = Allocator() );用[first,last)区间中的元素构造set
set ( const set& x);拷贝构造

3.3set的迭代器

函数声明功能
iterator begin()返回set中起始位置元素的迭代器
iterator end()返回set中最后一个元素后面的迭代器
const_iterator cbegin() const返回set中起始位置元素的const迭代器
const_iterator cend() const返回set中最后一个元素后面的const迭代器
reverse_iterator rbegin()返回set第一个元素的反向迭代器,即end
reverse_iterator rend()返回set最后一个元素下一个位置的反向迭代器, 即rbegin
const_reverse_iterator crbegin() const返回set第一个元素的反向const迭代器,即cend
const_reverse_iterator crend() const返回set最后一个元素下一个位置的反向const迭 代器,即crbegin
#include<iostream>
#include<map>
#include<set>
using namespace std;
void test1()
{
	set<int> s;
	s.insert(5);
	s.insert(1);
	s.insert(6);
	s.insert(3);
	s.insert(4);
	s.insert(5);
	s.insert(1);
	set<int>::iterator it = s.begin();
	while (it!=s.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

}
int main()
{
	test1();

	return 0;
}

set的遍历是有序的且会去重 

3.4set的容量

函数声明功能介绍
bool empty ( ) const检测set是否为空,空返回true,否则返回false
size_type size() const返回set中有效元素的个数

3.5set的修改操作

函数声明功能介绍
pair<iterator,bool> insert ( const value_type& x )在set中插入元素x,实际插入的是构成的 键值对,如果插入成功,返回该元素在set中的 位置,true>,如果插入失败,说明x在set中已经 存在,返回在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的元素的个数

 

void test2()
{
	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;
	//s.erase(start, finish);//区间删除

	while (start != finish)//左闭右开
	{
		cout << *start << " ";
		++start;
	}
	cout << endl;

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

 

3.6使用演示 

void test1()
{
	set<int> s;
	s.insert(5);
	s.insert(1);
	s.insert(6);
	s.insert(3);
	s.insert(4);
	s.insert(5);
	s.insert(1);
	set<int>::iterator it = s.begin();
	while (it!=s.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
	set<int>::iterator pos = s.find(5);
	if (pos != s.end())
	{
		s.erase(pos);
	}
	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;
	s.erase(3);//存在则删除
	s.erase(10);//该数若不存在则不做处理
	for (auto e : s)
	{
		cout << e << " ";
	}

}

 

multiset的使用

multiset与set的区别是:multiset允许重复个元素

由此引申出一些成员函数的区别

count: 返回的是元素x的个数

erase:删除序列中所有的x

find:返回序列中的第一个x

四、map的使用

1. map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元 素。

2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的 内容。键值key和值value的类型可能不同,并且在map的内部,key与value通过成员类型 value_type绑定在一起,为其取别名称为pair: typedef pair value_type;

3. 在内部,map中的元素总是按照键值key进行比较排序的。

4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序 对元素进行直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。

5. map支持下标访问符,即在[]中放入key,就可以找到与key对应的value。

6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。

4.1map的成员函数

构造

函数声明功能介绍
map()构造一个map

迭代器

 

容量

 

元素访问

mapped_type& operator[] (const key_type& k)返回去key对应的value

 修改及查找

insert

在map中插入键值对x,注意x是一个键值对,返回值也是键值对:iterator代表新插入 元素的位置,bool代表释放插入成功 

 

erase

 (1)删除pos位置上的元素

(2)删除键值为k的元素

(3)删除[first,last)区间中的元素

swap

 交换两个map中的元素

clear

将map中的元素清空

 

find

 

(1)在map中插入key为x的元素,找到返回该元 素的位置的迭代器,否则返回end

(2) 在map中插入key为x的元素,找到返回该元 素的位置的const迭代器,否则返回cend

count

返回key为x的键值在map中的个数,注意 map中key是唯一的,因此该函数的返回值 要么为0,要么为1,因此也可以用该函数来 检测一个key是否在map中

4.2map的使用

map的两个值是存到一个pair对象中的first(key)、second(val)

map的key(pair的first)不支持修改,val(pair的second)可以

pair的first有const修饰

void test_map1()
{
	map<string, string> dict;
	dict.insert(pair<string, string>("sort", "排序"));
	pair<string, string>kv("string", "字符串");
	dict.insert(kv);
	dict.insert({ "apple","苹果" });//C++11(构造函数)多参数的隐式类型转换
	//C++98常用
	dict.insert(make_pair("sort", "排序"));
	map<string, string>::iterator it = dict.begin();
	while (it!=dict.end())
	{
		//cout << (*it).first << " " << (*it).second << endl;
		cout << it->first << " " << it->second << endl;
		it++;
	}

}

map也有multi版本 

4.3额外内容

来看一下下面的代码

计算一个字符串数组中各字符串的出现次数


void test_map3()
{
	string arr[] = { "苹果","西瓜","香蕉","草莓","梨","苹果","香蕉","草莓","西瓜","苹果","西瓜" };
	//以水果为key(pair的first),出现次数为val(pair的second)
	map<string, int> countMap;
	for (auto& e : arr)
	{
		map<string, int>::iterator it = countMap.find(e);
		if (it != countMap.end())//出现过则second++
		{
			it->second++;
		}
		else//第一次出现就往map里存水果名字,出现次数是1
		{
			countMap.insert(make_pair(e, 1));
		}
	}
	for (auto& kv : countMap)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << endl;
}

 

再看一下下面的

void test_map3()
{
	string arr[] = { "苹果","西瓜","香蕉","草莓","梨","苹果","香蕉","草莓","西瓜","苹果","西瓜" };
	//以水果为key(pair的first),出现次数为val(pair的second)
	map<string, int> countMap;
	for (auto& e : arr)
	{
		countMap[e]++;
	}
	for (auto& kv : countMap)
	{
		cout << kv.first << ":" << kv.second << endl;
	}
	cout << endl;
}

 

一句代码就解决了存字符串和出现次数的问题

operator[]通过这个key去返回val的引用

如果map中没有这个key?operator是借助map.insert来实现的

 

看一下insert的返回值,pair<iterator,bool>(这个pair不是map的pair),可以理解为类pair里有两成员变量

上面是对insert的返回值的first解引用再取其second 

如果这个值(要插入的值)没有,插入成功(bool为真),pair的first(iterator)是新插入元素所在节点的迭代器;

如果这个值以及存在(插入失败),bool为假,pair的first(iterator)指向已有此元素的迭代器

 

 

简化一下 

V& operator[](const K& key)
{
	pair<iterator, bool> ret = insert(make_pair(key, V()));
	return ret.first->second;
}

 

operator[]的功能

1.插入

2.查找

3.修改 

4.查找+修改

void test_map2()
{
	map<string, string> dict;
	dict.insert(make_pair("sort", "排序"));
	dict.insert(make_pair("string", "字符串"));
	dict.insert(make_pair("sort", "xxx"));

	dict["left"];//插入
	cout << dict["sort"] << endl;//查找
	dict["sort"] = "abc";//修改
	dict["right"] = "右边";//插入+修改
	for (auto& kv : dict)
	{
		cout <<kv.first<< ":"<<kv.second<<endl;
	}
	cout << endl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/433779.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

django学习记录07——订单案例(复选框+ajax请求)

1.订单的数据表 1.1 数据表结构 1.2 数据表的创建 models.py class Order(models.Model):"""订单号"""oid models.CharField(max_length64, verbose_name"订单号")title models.CharField(max_length64, verbose_name"名称&…

Android6.0-14的兼容性

1.Android 6.0 ①新增运行时权限&#xff0c;危险权限需要动态申请 ②删除了对 Apache HTTP 客户端的支持&#xff0c; 解决方法&#xff1a;必须在build.gradle文件中声明以下编译时依赖项 android { useLibrary org.apache.http.legacy } 2.Android 8.0 ①允许安装未知来源…

15 实战:Kaggle房价预测 + 课程竞赛:加州2020年房价预测【李沐动手学深度学习课程笔记】

15 实战&#xff1a;Kaggle房价预测 课程竞赛&#xff1a;加州2020年房价预测【李沐动手学深度学习课程笔记】https://zhuanlan.zhihu.com/p/685343754 写在前面&#xff1a;这里格式很乱&#xff0c;代码直接去知乎copy 1 实战Kaggle比赛&#xff1a;预测房价 1.1 实现几个函…

C#实现选择排序算法

以下是使用C#实现选择排序算法的示例代码&#xff1a; using System;class SelectionSort {static void Main(string[] args){int[] arr { 64, 25, 12, 22, 11 };Console.WriteLine("排序前&#xff1a;");PrintArray(arr);SelectionSortAlgorithm(arr);Console.Wr…

STM32CubeMX学习笔记12 ---低功耗模式

在实际使用中很多产品都需要考虑低功耗的问题&#xff0c;STM32F10X提供了三种低功耗模式&#xff1a;睡眠模式&#xff08;Sleep mode&#xff09;、停机模式&#xff08;Stop mode&#xff09;和待机模式&#xff08;Standby mode&#xff09;。这些低功耗模式可以有效减少系…

【AI视野·今日NLP 自然语言处理论文速览 第八十三期】Wed, 6 Mar 2024

AI视野今日CS.NLP 自然语言处理论文速览 Wed, 6 Mar 2024 Totally 74 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers MAGID: An Automated Pipeline for Generating Synthetic Multi-modal Datasets Authors Hossein Aboutalebi, …

Vue-04

Vue 指令 指令补充 指令修饰符&#xff1a;通过"."指明一些指令后缀&#xff0c;不同后缀封装了不同的处理操作 → 简化代码 按键修饰符 keyup.enter → 键盘回车监听 在input中使用keyup.enter&#xff0c;这个时候按enter键也能实现添加&#xff0c;和点击按钮实…

Redis的散列插槽及故障转移

散列插槽 散列插槽原理类似于一个哈希散列表&#xff0c;通过哈希算法来映射插槽&#xff0c;并为redis节点分配插槽区间&#xff0c;插槽的所有范围是0~16383 数据key不是与节点绑定&#xff0c;而是与插槽绑定。redis会根据key的有效部分计算插槽值&#xff0c;分两种情况&a…

第十三届蓝桥杯大赛软件赛省赛C/C++ 大学 B 组 统计子矩阵

#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<vector> #include<queue>using namespace std;int cnt,temp; int n,m,K; int a[505][505]; int pre[505][505];//二维前缀和void sol() {cin>>…

【Linux】gcc升级13.2.0

错误信息 g: error: unrecognized command line option ‘-stdgnu14’ -stdc14需要g5.2以上&#xff0c;而centos默认的g只有4.8.5&#xff0c;所以&#xff0c;要做的事情&#xff0c;是升级g 下载gcc 官网下载: https://ftp.gnu.org/gnu/gcc/wget https://ftp.gnu.org/gnu/…

liunx自动构建化工具make/makefile

liunx自动化构建工具 依赖关系和依赖方法makefile 文件格式 第一个项目 进度条牛刀小试 倒计时简单模版 makefile 的多文件编程 依赖关系和依赖方法 依赖关系&#xff1a;依赖关系是文件之间的关系。 依赖方法&#xff1a;依赖方法是文件之间相互作用的方法。通过方法产生关系…

java网络编程 02 socket

01.socket定义 02.TCP编程 import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket;public class clientSocket {public static void main(String[] args) throws IOException {Socket socket new Socket(Inet…

HTTP协议与HTTPS协议

HTTP与*HTTPS HTTP协议HTTP请求的通信过程HTTP优点 HTTPS协议HTTPS优点SSL/TLS的工作原理?*公钥传递的信赖&#xff1f;*通过中间CA机构传输 HTTP协议 HTTP协议是一个无状态的协议&#xff0c; 服务器不维护任何有关客户端之前所发请求的消息。 是一种懒政&#xff0c;有状态协…

基于selenium自动化索引点击

小鹅快速刷题&#xff0c;根据selenium和xpath定位题干&#xff0c;使用模糊匹配fuzzywuzzy库查找题目匹配答案&#xff0c;自动点击&#xff0c;完成后更新题库 先导入基本包&#xff0c;准备好题库 from fuzzywuzzy import process from selenium import webdriver import …

9、Linux-安装JDK、Tomcat和MySql

目录 一、安装JDK 1、传输JDK文件&#xff08;.tar.gz&#xff09; 2、解压 3、备份环境变量 4、配置环境变量 5、重新加载环境变量 6、验证&#xff08;java -version&#xff09; 二、安装Tomcat 1、传输文件&#xff0c;解压到/usr/local 2、进入Tomcat的bin目录 …

如何从产品的角度做好内容营销?媒介盒子支招

内容运营就是指将生产传播内容并进行重组&#xff0c;去满足用户的内容消费需求&#xff0c;想要提高内容运营的效果&#xff0c;媒介盒子认为可以从产品出发&#xff0c;将内容运营与品牌产品相结合。那么应该怎么做呢&#xff1f;接下来就让媒介盒子告诉你。 一、 场景化内容…

Android岗面试,android内存优化面试题

前言 曾听过很多人说Android学习很简单&#xff0c;做个App就上手了&#xff0c;工作机会多&#xff0c;毕业后也比较容易找工作。这种观点可能是很多Android开发者最开始入行的原因之一。 在工作初期&#xff0c;工作主要是按照业务需求实现App页面的功能&#xff0c;按照设…

太惊艳了!多微信管理利器,让你事半功倍!

作为现代社交媒体的主要平台之一&#xff0c;微信在商务领域中扮演着重要的角色。为了提高我们的工作效率&#xff0c;微信管理系统应运而生。 这个系统可以同时登录多个微信账号&#xff0c;并进行统一管理。除了便捷的登录管理功能外&#xff0c;微信管理系统还提供了许多实…

达梦数据库使用数据库迁移工具弹窗报错“获取模式失败”的解决办法

在使用数据库迁移工具Data Transfer Service时&#xff0c;在下面这个页面点击下一步之后报错“获取模式失败” 为什么会失败呢&#xff1f;我们去看看报错 这里显示系统处于MOUNT状态&#xff0c;这可能是出错的原因。我们去查看数据库状态。 发现是mount状态。 因为mount状态…

薪资18K需要什么水平?来看看97年测试工程师的面试全过程…

我的情况 大概介绍一下个人情况&#xff0c;男&#xff0c;本科&#xff0c;三年多测试工作经验&#xff0c;懂python&#xff0c;会写脚本&#xff0c;会selenium&#xff0c;会性能&#xff0c;然而到今天都没有收到一份offer&#xff01;从年后就开始准备简历&#xff0c;年…
最新文章