C++STL关联容器(map set)

1.关联容器

1.1分类

容器 模板 特点
映射容器 map 一对多映射,基于关键字快速查找,不允许重复值
多重映射容器 multimap 一对多映射,基于关键字快速查找,允许重复值
集合容器 set 快速查找,不允许重复值
多重集合容器 multiset 快速查找,允许重复值

2map 容器

2.1概念

1:map: 是key-value构成的集合,key必须唯一。 映射是关联容器,它存储由键值和映射值组合而成的元素,
2:map主要用来查找key对应value,要求key必须是可排序的,键值通常用于排序和唯一标识元素必须支持**<比较运算符**。
3:map默认是以key升序存放键值对<key,value>数据,比较适合二分查找映射通常实现为二进制搜索树。。

4:映射容器通过键访问单个元素的速度通常比无序的映射容器慢,但它们允许基于子集的顺序直接迭代。

5:映射中的映射值可以使用括号运算符((operator[])通过其对应的键直接访问。

2.2map内部结构

1:map使用pair<key,value>类模板保存key与value,
2:pair<key,value>有两个public成员变量 :first和second,first存放key,second存放value。
3:在map里面可以使用map<>::value_type表示pair<key,value>。
因为:

typedef pair<key,value> value_type;

2.3 初始化

3种方式

//1默认构造(可带参数)
map<string,string> dict;
dict["apple"]="苹果";
dict["orange"]="橙子";
dict["banana"]="香蕉";
//2复制构造
map<string,string> dict1(dict)
//3范围赋值构造
std::map<char,int> first;

  first['a']=10;
  first['b']=30;
  first['c']=50;
  first['d']=70;

  std::map<char,int> second (first.begin(),first.end());

初始化时必须给map<>类模板同时设置key与value的类型模板实参。
实参类型不限于基本类型、类类型(class、struct、union),还可以是容器模板。

2.4 基本操作

迭代器
在这里插入图片描述

在这里插入图片描述

2.5添加数据/

1:insert插入pair<>数据

map<string,string> dict;
	//添加数据
	dict["apple"]="苹果";
	dict["orange"]="橙子";
	dict["banana"]="香蕉";
	cout<<dict["apple"]<<endl;

	dict.insert(pair<string,string>("watermalon","西瓜"));
	dict.insert(make_pair("watermalon","西瓜"));
	//当dict中没有UFO这个值  系统就是自动创建一个UFO值的pair放进map中
	//dict["UFO"];

解决方法:

//先查找有没有UFO 在进行【】操作
if(dict.count("UFO")!=0&&dict["UFO"=="?????"])

2:insert插入map<>::value_type成员数据

//map<string,string>::value_type和pair<string,string>一样
m.insert(map<int,int>::value_type(i,i*10));

3: insert插入make_pair数据

make_pair是一个函数模板,类似与如下实现:
template<class K,class V)
inline pair<K,V> make_pair(K const& k,V const& v){
    return pair<K,V>(k,v);
}
dict.insert(make_pair("watermalon","西瓜"));

4: 下标运算符[]添加数据

map<string,string> dict;
	//添加数据
	dict["apple"]="苹果";
	dict["orange"]="橙子";
	dict["banana"]="香蕉";

2.6 遍历

迭代器for循环

//遍历
	map<string,string>::iterator it=dict.begin();
	while(it!=dict.end()){
		cout<<it->first<<","<<it->second<<endl;
		it++;
	}	

for_each()循环

void Print(const pair<string,string>& p){
	cout<<p.first<<","<<p.second<<endl;

}
for_each(dict.begin(),dict.end(),Print);

最简单写法: C++11 for-loop-scope迭代器写法

for(auto p : m){
    cout << "[" << p.first << "]=" << p.second << endl;
}

2.7查找

//count()判断key是否存在
if(m.count(key) == 1){
     ...
}
//find()判断key是否存在以及位置
map<int,int>::iterator it = m.find(key);
if(m.end() != it){
     ...
}
//下标运算符[]
m[key];//如果key不存在,默认创建。

2.8 删除

//删除
	dict.erase("apple");
//迭代器删除
m.erase(m.begin());
//区域删除
m.erase(it_a,it_b);

2.9排序

默认按照key升序排列。自定义排序是,可以在实例化加上key的comp仿函数, 重载<运算符。

//意思是 如果类型为类 其升序有自己的定义方法那要不定义comp仿函数        要不定义<重载运算符
map<key类型,value类型,comp> m;

3set

3.1

1“:集合是按照特定顺序存储唯一元素的容器。
2:在集合中,元素的值还标识它(该值本身就是类型T的键),并且每个值都必须是唯一的。集合中元素的值不能在容器中修改一次(元素总是常量),但可以从容器中插入或移除
3:在内部,集合中的元素总是按照其内部比较对象(类型为Compare)指示的特定严格弱排序条件进行排序。
4:集合容器访问单个元素的键通常比无序集合容器慢,但它们允许基于其顺序对子集进行直接迭代。
5:集合通常实现为二进制搜索树。

3.2基本和map相同

set,map的key会自动排序和去重

#include<iostream>
#include<set>
#include<vector>
#include<algorithm>
using namespace std;
/*set特点
 * 	1:升序
 * 	2:每个值唯一 不重复
 * 	3:每个都是确定的
 *
 *
 * */
void Print(int n){
	cout<<n<<" ";
}
int main(){
	int arr[]={3,2,1,5,6,8,7};
	set<int> s(arr,arr+7);
	for_each(s.begin(),s.end(),Print);
	cout<<endl;
	//判断值出现过一次的数
	int arr1[]={3,3,1,5,5,8,8};
	vector<int> v(arr1,arr1+7);
	set<int> s1;
	for(int i=0;i<v.size();++i){
		if(s1.count(v[i])==0){
			s1.insert(v[i]);
		}else{
			s1.erase(v[i]);
		}

	}
	cout<<*s1.begin()<<endl;

}

4容器比较

在这里插入图片描述

发布了27 篇原创文章 · 获赞 4 · 访问量 1332

猜你喜欢

转载自blog.csdn.net/weixin_45639955/article/details/104317145