文章目录
- set/multiset对象的构造
- set/multiset的常规操作
- set/multiset其他操作
- map/multimap构造函数
- map/multimap元素访问
- map/multimap修改
set/multiset容器
set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。
set采用红黑树变体的数据结构实现,红黑树属于平衡二叉树。在插入操作和删除操作上比vector快。
multiset与set的区别:set支持唯一键值,每个元素值只能出现一次;而multiset中同一值可以出现多次。
不可以直接修改set或multiset容器中的元素值,因为该类容器是自动排序的。如果希望修改一个元素值,必须先删除原有的元素,再插入新的元素。
set/multiset对象的构造
set();
set(const set& _Right);
explicit set(const key_compare& _Pred);
set(_Iter _First, _Iter _Last);
set(_Iter _First, _Iter _Last, const key_compare& _Pred);
set/multiset的常规操作
bool empty();
size_t size();
size_t max_size();
pair<iterator, bool> insert(const value_type& _Val);
iterator insert(const value_type& _Val);
void insert(_Iter _First, _Iter _Last);
void insert(initializer_list<value_type> _Ilist);
iterator erase (const_iterator where); //返回下一个元素的位置
size_type erase (const value_type& val); //返回删除元素的个数,对于set来说,永远是1(set的值不能重复)
iterator erase (const_iterator first, const_iterator last); //区间删除
void swap(const &right); //交换set
void clear(); //清空所有元素
template <class... _Valtys>
pair<iterator, bool> emplace(_Valtys&&... _Vals);
//提示从whrere开始找,不是插入到where的位置,如果vals满足排在where指向的值的后面,那么将提高速度,否则无影响
template <class... _Valtys>
iterator emplace_hint(const_iterator _Where, _Valtys&&... _Vals)
代码示例:
int main()
{
//multiset与set的区别:set支持唯一键值,每个元素值只能出现一次;而multiset中同一值可以出现多次。
set<int> a{ 1,1,2,2,3,3,4,5,6 };
multiset<int> b{ 1,1,2,2,3,3,4,5,6 };
cout << "set容器的删除永远返回:" << a.erase(1) << endl;
cout << "multiset容器的删除可以有多个:" << b.erase(1) << endl;
/*
set: 1 2 3 4 5 6
multiset: 1 1 2 2 3 3 4 5 6
*/
for (auto& x1 : a)
{
cout << x1 << " ";
}
cout << endl;
for (auto& x2 : b)
{
cout << x2 << " ";
}
cout << endl;
return 0;
}
set/multiset其他操作
有关算法的操作,我将会在算法那一节集中讲解。
//两个返回的都是一样的
key_compare key_comp()const;
value_compare value_comp()const;
iterator find(const key_type& _Keyval);//在容器中搜索与val等效的元素,如果找到则返回一个迭代器,否则返回end迭代器。
size_t count(const key_type& _Keyval); //在容器中搜索与val等效的元素,并返回匹配数。
//与排序规则有关
iterator lower_bound(const key_type& _Keyval);//找到第一个大于或者等于keyval的值
iterator upper_bound(const key_type& _Keyval);//找到第一个大于keyval的值
pair<iterator, iterator> equal_range(const key_type& _Keyval)
map\multimap容器
map(映射)是关联容器,用于存储按特定顺序由键值和映射值的组合形成的元素,即(key,value)对。它提供基于key的快速检索能力。
map中key值是唯一的。集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。
map的具体实现采用红黑树变体的平衡二叉树的数据结构。在插入操作和删除操作上比vector快。
map可以直接存取key所对应的value,支持[]操作符,如map[key]=value。
multimap与map的区别:map支持唯一键值,每个key只能出现一次;而multimap中同一key可以出现多次。map支持[]操作符,但是multmap不支持
map <string, int> a{ {"喜羊羊",2},{"喜羊羊",2},{"虎太郎",3},{"懒洋洋",10} };
multimap <string, int> a1{ {"喜羊羊",2},{"喜羊羊",2},{"虎太郎",3},{"懒洋洋",10} };
map不可以出现重复的key,multimap允许
map/multimap构造函数
map();
map(const map& _Right);
map(const key_compare& _Pred);
map(_Iter _First, _Iter _Last);
map(_Iter _First, _Iter _Last, const key_compare& _Pred);
注意:map的构造函数必须使用 {}来构造,因为map包含一个string和int,他们是一对 键值对
,一个关键字对应一个数值,他们是绑在一起的。
注意:map的返回值为一个pair类型。 pair类型有first和second成员,pair的first指向map的第一个数据类型,即string; pair的second指向map的第二个数据类型,即int类型,可以使用 . 运算符来访问:
pair<const string, int> aPoint;
map <string, int> a{ {"喜羊羊",2},{"虎太郎",3},{"懒洋洋",10} };
for (auto& x : a)
{
cout << x.first << ":" << x.second << endl;
}
map/multimap元素访问
mapped_type& operator[](key_type&& keyval); //根据key获取value
mapped_type& at(const key_type& _Keyval);
map支持 []运算符来访问元素,即[]里的是一个关键字,可以类似于数组,使用[]来指定关键字,然后找到其所包含的第二个数据,int。
cout << a["喜羊羊"] << " " << a["懒洋洋"] << endl;
cout << a.at("虎太郎") << endl;
map/multimap修改
insert
insert插入的是由键值对组成的pair<key_type,mapped_type>,可称为对组
key_type 键类型
mapped_type 值类型
value_type map装的元素内存,即pair<key_type,mapped_type>
pair<iterator,bool> insert (const value_type& val);
pair<iterator,bool> insert (value_type&& val);
假设 map<int, string> stu;
一、通过pair的方式插入对象
stu.insert(pair<int, string>(1, "maye"));
二、通过make_pair的方式插入对象
stu.insert(make_pair(2, "zoey"));
三、通过value_type的方式插入对象
stu.insert(map<int, string>::value_type(3, "lisa"));
四、通过数组的方式插入值
stu[3]= "取个名字好难";
stu[4] = "有人@我";
前三种方法,采用的是insert()方法,该方法返回值为pair<iter,bool>
iterator 指向插入的pair,bool标识是否插入成功
第四种方法非常直观,但存在一个性能的问题。
按key(3)插入元素时,若map中没有key(3),则键值对插入map,若key(3)已经存在,则修改key(3)对于的值。
string strName = stu[2]; //获取key对于的值
只有当stu存在2这个键时才是正确的取操作,否则会自动插入一个实例,键为2,值为初始化值。
总结:插入的几种方式
//通过pair来插入键值对
auto it=a.insert(pair<string, int>("熊大", 15));
cout <<"插入成功了吗?"<<boolalpha<<it.second<<"\t"<< it.first->first << ": " << it.first->second << endl;
//通过make_pair来插入键值对
it=a.insert(make_pair<string, int>("小灰灰", 55));
cout << "插入成功了吗?" << boolalpha << it.second << "\t" << it.first->first << ": " << it.first->second << endl;
//通过value_type来插入
it=a.insert(map<string, int>::value_type("熊二", 66));
cout << "插入成功了吗?" << boolalpha << it.second << "\t" << it.first->first << ": " << it.first->second << endl;
//通过数组方式插入
a["美羊羊"] = 666;
a["茶人"] = 999;
注意:insert插入的返回值为pair<iter,bool>
- pair的第一个参数是iter,iter是一个指向map的一对键值对的pair,所以为了访问此元素,可以首先使用
pair.first->first/second
首先获取迭代器,然后再获取map的元素。 - 插入后,他们的关键字会自动按照顺序排序,如图为首字母的顺序。
earse
//删除key为keyval的元素,返回删除成功的数量
size_t erase(const key_type& _Keyval);
//删除[first,last)区间元素,返回last
iterator erase(const_iterator _First, const_iterator _Last);
//删除where指向的元素,返回下一个元素迭代器
iterator erase(const_iterator _Where);
示例:
//删除关键字对应的键值对
a.erase("喜羊羊"); //返回size_t 即删除的个数
//删除区间
auto it1 = ++a.begin();
++it1;
++it1;
a.erase(a.begin(),it1);
首先会删除指定关键字的键值对,然后第二个接受一个区间,会删除区间里的内容。
emplace
//就地构造,传
template <class... Args>
pair<iterator,bool> emplace (Args&&... args);
template <class... Args>
iterator emplace_hint (const_iterator position, Args&&... args);
//stu.emplace(12, "duck"); //key,mapped
map操作
void clear();
bool empty();
size_t size();
size_t max_size();
//查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回map.end();
iterator find(const key_type& _Keyval);
//返回容器中key为keyval的pair个数,对于map要么是0,要么是1。对multimap来说,值可能大于1。
size_type count(const key_type& _Keyval);
iterator lower_bound(const key_type& _Keyval);
iterator upper_bound(const key_type& _Keyval);
//返回
pair<iterator, iterator> equal_range(const key_type& _Keyval);