文章目录
- 第六章:关联式容器
- 1.set
- (1)set的特点
- (2)set的构造
- (3)set的查找操作 (set访问元素)
- (4)set的插入操作、pair
- (5)set的遍历
- 2.map
- (1)map的特点
- (2)map的构造
- (3)map的查找操作
- (4)map的插入操作
- (5)map的下标操作 (重点)
- (5)map的遍历
第六章:关联式容器
1.set
(1)set的特点
①set有去重效果,元素必须唯一
②set会默认升序排序
(2)set的构造
1.默认的无参构造函数,创建一个空集合
set<int> nums;
2.初始化列表
set<int> nums = {1,2}; //推荐使用
set<int> nums2{3,4};
set<int> nums3({5,6});
3.复制或赋值
set<int> nums3 = nums2; //推荐使用
set<int> nums3(nums); //C++可以用小括号赋值
4.用另一个set的迭代器复制或赋值
set<int> nums4(nums2.begin(),nums2.end());
(3)set的查找操作 (set访问元素)
0.set不支持下标访问
set<int> nums = {1,2,3};
set[0]; //error
1.count()
count()本是查找元素在容器中的个数。而set有去重效果,最多存一份。所以返回值要么是1(存在),要么是0(不存在)。
size_t cnt = nums2.count(30);
cout << cnt << endl;
2.find()
若能找到,返回迭代器。
set<int>::iterator it = nums2.find(2);
if(it != nums2.end()){cout << "该元素存在:" << *it << endl;
}else{cout << "该元素不存在。" << endl;
}
(4)set的插入操作、pair
insert的返回类型是pair<iterator, bool>。
pair定义在头文件< utility >中,类似于结构体,可以存储两种不同类型的变量。
#include <utility>
void test1(){pair<int,string> num = {1,"wangdao"};cout << num.first << ":" << num.second << endl;pair<int,string> num2(2, "hello");cout << num2.first << ":" << num2.second << endl;string str("world");pair<string, double> num3(str, 4.7);cout << num3.first << ":" << num3.second << endl;
}
insert的返回值:pair<iterator, bool>
1.插入1个元素
pair<set<int>::iterator, bool> ret = nums.insert(2);
//auto ret = nums.insert(2);
if(ret.second){cout << "插入成功:" << *(ret.first) << endl;
}else{cout << "插入失败,该元素已存在:" << *(ret.first) << endl;
}
2.插入一堆元素
(1)迭代器插入
void insert(InputIt first, InputIt last); //插入一堆元素,返回类型就是void
set<int> nums2{7,8,9,20,35};
nums.insert(nums2.begin(), nums2.end());
(2)初始化列表插入
nums.insert({100,99,98,97});
for(auto & ele : nums){cout << ele << " ";
}
cout << endl;
(5)set的遍历
set不支持下标访问。不能用普通for循环进行遍历。
可以 迭代器遍历、增强for循环遍历
//set遍历
void test3(){set<int> nums{1,2,3,4,5};//nums[0]; //set不支持下标操作//1.增强for循环for(auto & ele : nums){cout << ele << " ";}cout << endl;//2.迭代器for(auto it = nums.begin(); it != nums.end(); ++it){cout << *it << " ";}cout << endl;
}
- set容器不支持下标访问,因为没有operator[] 重载函数
- 不能通过set的迭代器直接修改key值,set的底层实现是红黑树,结构稳定,不允许直接修改。
2.map
(1)map的特点
①map有去重效果,key值必须唯一:创建map对象时,舍弃了一些元素,key值相同的元素被舍弃。key不同,即使value相同也能保留
②map会自动升序排序:默认以key值为参考进行升序排列
(2)map的构造
map中存放的元素的类型是pair类型(键值对),构造map有三种方式:
void test0(){map<int,string> number = {{1,"beijing"},{2,"world"},{3,"wangdao"},pair<int,string>(4,"hubei"),pair<int,string>(5,"wangdao"),make_pair(9,"shenzhen"),make_pair(3,"beijing"),make_pair(6,"shanghai")};
}
①key值相同,插入失败。根据key值来去重。
②按照key值升序排序
思考,如果key是自定义类型Point,如何重载,让编译器知道Point的排序方式?
(3)map的查找操作
1.count()
查找key,找到返回1,没找到返回0
2.find()
查找key,找到返回元素的迭代器,没找到返回尾迭代器end()
(4)map的插入操作
insert
1.插入一个元素
2.插入一组元素,迭代器
3.插入一组元素,初始化列表
(5)map的下标操作 (重点)
map进行下标访问时,
(1)下标是key值,返回对应的value。
(2)如果进行下标操作时下标值传入一个不存在的key,那么会将这个key和空的value(默认的value值)插入到map中。
(3)下标访问可以进行写操作 (只是对value进行写操作,不影响排序)
map底层也是红黑树,但是写操作修改的是value,不影响key值,因此不会影响排序。而set只有key值,不可以进行下标操作。
(5)map的遍历
1.使用迭代器方式遍历map,注意访问map的元素pair的内容时的写法
for(auto it = number.begin(); it != number.end(); ++it){cout << it->first << " " << it->second << endl; //*(). 等价于 ->
}
cout << endl;
map<int,string>::iterator it = number.begin();
while(it != number.end()){cout << (*it).first << " " << (*it).second << endl;++it;
}
cout << endl;
2.使用增强for循环变量map
for(auto & ele : _dict){cout << ele.first << " " << ele.second << endl;
}