目录
1.set
1.1介绍set - C++ Reference
1.2set的使用
1. set的模板参数列表
2.set构造
3.常用接口
1.3multiset
2.map
2.1关联式容器,键值对
2.2map的介绍 map - C++ Reference
2.3map的常用接口
1.insert
2. operator[]
3.erase等
4.multipmap
1.set
1.1介绍set - C++ Reference
1.set是按照一定次序存储元素的容器。
2.set在底层是用二叉搜索树(红黑树)实现的。
3. 在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。
set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。
注意:
1. 与map/multimap不同,map/multimap中存储的是真正的键值对,set中只放
value,但在底层实际存放的是由构成的键值对,插入元素时,只需要插入value即可。
2.set中的元素不可以重复,元素默认按照小于来比较 ,使用set的迭代器遍历set中的元素,可以得到有序队列。
1.2set的使用
1. set的模板参数列表
2.set构造
3.常用接口
直接查找某个值
支持插入一段区间,一个值,具体某个位置上插入(很少用)
删除一段区间,某个位置上的值,一个值
返回元素个数
void test1()
{
set s;
s.insert(3);
s.insert(8);
s.insert(2);
s.insert(1);
s.insert(1);
s.insert(6);
s.insert(9);
s.insert(1);
s.insert(9);
set::iterator it = s.begin();
while (it != s.end())//进行排序,去重
{
cout << *it << " ";
it++;
}
}
set::iterator pos = s.find(4);
if (pos != s.end())
{
cout << "set.find找到了" << endl;
}
else
{
cout << "未找到" << endl;
}
cout << s.erase(3) << endl;//删除返回元素的个数
cout << s.erase(20) << endl;//失败返回0
pos = s.find(100);
//s.erase(pos); //这样删除不存在的数会报错
if (pos != s.end())
{
s.erase(pos);
}
if (s.count(6))//可用来判断元素是否纯在
{
cout << "6存在" << endl;
}
结果:
lower_bound:返回大于等于val的值
upper_bound:返回大于val的值
例如:
void test2()
{
set s;
s.insert(2);
s.insert(4);
s.insert(1);
s.insert(6);
for (auto& ch : s)
{
cout << ch << " ";
}
cout << endl;
set::iterator lowit = s.lower_bound(2);//返回>=2位置的迭代器
set::iterator upit = s.upper_bound(5);//返回>5位置的迭代器
s.erase(lowit, upit);//左闭右开。刚好把[2-5]间的值删除
for (auto& ch : s)
{
cout << ch << " ";
}
cout << endl;
}
结果:
1.3multiset
介绍:与set类似,但可存储相同值的元素
void test3()
{
multiset s;
s.insert(2);
s.insert(4);
s.insert(3);
s.insert(8);
s.insert(8);
s.insert(8);
s.insert(12);
s.insert(3);
s.insert(7);
s.insert(5);
for (auto& ch : s)
{
cout << ch << " ";
}
cout << endl;
cout << s.erase(8) << endl;//会把8全部删除,返回删除的元素个数
cout <<"3的个数:" << s.count(3) << endl;//返回查找的元素个数
for (auto& ch : s)
{
cout << ch << " ";
}
}
结果:
2.map
2.1关联式容器,键值对
介绍:
STL中的部分容器,比如:vector、list、deque、forward_list(C++11)等,
这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。
关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结构的
键值对,在数据检索时比序列式容器效率更高。
键值对:用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代
表键值,value表示与key对应的信息
2.2map的介绍 map - C++ Reference
1. map
是关联容器,它按照特定的次序
(
按照
key
来比较
)
存储由键值
key
和值
value
组合而成的元
素。
2.
在
map
中,键值
key
通常用于排序和唯一地标识元素,而值
value
中存储与此键值
key
关联的
内容。键值
key
和值
value
的类型可能不同,并且在
map
的内部,
key
与
value
通过成员类型
value_type
绑定在一起,为其取别名称为
pair。
3. map
通常被实现为二叉搜索树
(
更准确的说:平衡二叉搜索树
(
红黑树
))
。
4.map
中的
key
是唯一的,并且不能被修改。
5.
支持
[]
操作符,
operator[]
中实际进行插入查找。
key: 键值对中key的类型
T: 键值对中value的类型
Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比
较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户
自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的
空间配置器
2.3map的常用接口
大部分与set是类似的,不过多介绍。
1.insert
make_pair是一个函数模板
举例:
void test3()
{
map m;
m.insert(pair("sort", "排序"));
pair kv("insert", "插入");
m.insert(kv);
m.insert(make_pair("left", "左边"));
m.insert(make_pair("English", "英语"));
map::iterator it = m.begin();
while (it != m.end())
{
cout << it->first << "-" << it->second << " ";
++it;
}
cout << endl;
for (auto& ch : m)
{
cout << ch.first << "-" << ch.second << " ";
}
cout << endl;
}
结果:按key类型进行排序
insert的返回值:是一个pair,插入成功,iterator是指向新插入元素的迭代器,bool为true;插入失败,iterator是当前元素的的迭代器,bool为false
例如:
void test4()
{
string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
map countMap1;
for (auto& str : arr)//统计水果的个数
{
map::iterator it = countMap1.find(str);
if (it != countMap1.end())
{
it->second++;
}
else
{
countMap1.insert(make_pair(str, 1));
}
}
map countMap2;
for (auto& str : arr)
{
pair
结果:
2. operator[]
源码实现类似于:
mapped_type& operator[] (const key_type& k)
{
pair ret = insert(make_pair(k, mapped_type()));
//return (*(ret.first)).second;
return ret.first->second;//返回的是第二个参数的引用,可以修改
}
mapped_type是第二个参数的类型,上面是构造的匿名对象。
可充当查找,修改,插入的功能
如果插入数据成功(返回的是插入新元素的第二个参数的引用),如果数据存在,返回的是该数据的第二个参数的引用,也可以把它修改。
举例:
void test5()
{
string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
map countMap;
for (auto& str : arr)
{
countMap[str]++;
}
for (auto& ch : countMap)
{
cout << ch.first << "-" << ch.second << " ";
}
cout << endl;
map m;
m.insert(make_pair("suffer", "痛苦"));
m.insert(make_pair("extend", "扩大"));
m.insert(make_pair("left", "左边"));
m["suffer"] = "遭受";//查找+修改
m["right"] = "右边";//插入新数据
for (auto& ch : m)
{
cout << ch.first << "-" << ch.second << " ";
}
cout << m["extend"] << endl;//查找该数据
}
结果:
3.erase等
void test6()
{
string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
map m;
for (auto& str : arr)
{
m[str]++;
}
m.erase("苹果");
for (auto& ch : m)
{
cout << ch.first << "-" << ch.second << " ";
}
}
结果:
桃-1 西瓜-1 西红柿-1 香蕉-2
其余接口与set也是类似的,这里不再叙述
4.multipmap
介绍:支持插入相同元素,其余与map是类似的,但不支持[].
1.2set的使用
1. set的模板参数列表
2.set构造
3.常用接口
直接查找某个值
支持插入一段区间,一个值,具体某个位置上插入(很少用)
删除一段区间,某个位置上的值,一个值
返回元素个数
void test1() { sets; s.insert(3); s.insert(8); s.insert(2); s.insert(1); s.insert(1); s.insert(6); s.insert(9); s.insert(1); s.insert(9); set ::iterator it = s.begin(); while (it != s.end())//进行排序,去重 { cout << *it << " "; it++; } }
set::iterator pos = s.find(4); if (pos != s.end()) { cout << "set.find找到了" << endl; } else { cout << "未找到" << endl; } cout << s.erase(3) << endl;//删除返回元素的个数 cout << s.erase(20) << endl;//失败返回0 pos = s.find(100); //s.erase(pos); //这样删除不存在的数会报错 if (pos != s.end()) { s.erase(pos); } if (s.count(6))//可用来判断元素是否纯在 { cout << "6存在" << endl; }
结果:
lower_bound:返回大于等于val的值
upper_bound:返回大于val的值
例如:
void test2() { sets; s.insert(2); s.insert(4); s.insert(1); s.insert(6); for (auto& ch : s) { cout << ch << " "; } cout << endl; set ::iterator lowit = s.lower_bound(2);//返回>=2位置的迭代器 set ::iterator upit = s.upper_bound(5);//返回>5位置的迭代器 s.erase(lowit, upit);//左闭右开。刚好把[2-5]间的值删除 for (auto& ch : s) { cout << ch << " "; } cout << endl; }
结果:
1.3multiset
介绍:与set类似,但可存储相同值的元素
void test3() { multisets; s.insert(2); s.insert(4); s.insert(3); s.insert(8); s.insert(8); s.insert(8); s.insert(12); s.insert(3); s.insert(7); s.insert(5); for (auto& ch : s) { cout << ch << " "; } cout << endl; cout << s.erase(8) << endl;//会把8全部删除,返回删除的元素个数 cout <<"3的个数:" << s.count(3) << endl;//返回查找的元素个数 for (auto& ch : s) { cout << ch << " "; } }
结果:
2.map
2.1关联式容器,键值对
介绍:
STL中的部分容器,比如:vector、list、deque、forward_list(C++11)等, 这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身。 关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是结构的 键值对,在数据检索时比序列式容器效率更高。
键值对:用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代 表键值,value表示与key对应的信息
2.2map的介绍 map - C++ Reference 1. map 是关联容器,它按照特定的次序 ( 按照 key 来比较 ) 存储由键值 key 和值 value 组合而成的元 素。 2. 在 map 中,键值 key 通常用于排序和唯一地标识元素,而值 value 中存储与此键值 key 关联的 内容。键值 key 和值 value 的类型可能不同,并且在 map 的内部, key 与 value 通过成员类型 value_type 绑定在一起,为其取别名称为 pair。 3. map 通常被实现为二叉搜索树 ( 更准确的说:平衡二叉搜索树 ( 红黑树 )) 。 4.map 中的 key 是唯一的,并且不能被修改。 5. 支持 [] 操作符, operator[] 中实际进行插入查找。
key: 键值对中key的类型 T: 键值对中value的类型 Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照小于来比 较,一般情况下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户 自己显式传递比较规则(一般情况下按照函数指针或者仿函数来传递) Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的 空间配置器
2.3map的常用接口
大部分与set是类似的,不过多介绍。
1.insert
make_pair是一个函数模板
举例:
void test3() { mapm; m.insert(pair ("sort", "排序")); pair kv("insert", "插入"); m.insert(kv); m.insert(make_pair("left", "左边")); m.insert(make_pair("English", "英语")); map ::iterator it = m.begin(); while (it != m.end()) { cout << it->first << "-" << it->second << " "; ++it; } cout << endl; for (auto& ch : m) { cout << ch.first << "-" << ch.second << " "; } cout << endl; }
结果:按key类型进行排序
insert的返回值:是一个pair
例如:
void test4() { string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" }; mapcountMap1; for (auto& str : arr)//统计水果的个数 { map ::iterator it = countMap1.find(str); if (it != countMap1.end()) { it->second++; } else { countMap1.insert(make_pair(str, 1)); } } map countMap2; for (auto& str : arr) { pair
结果:
2. operator[]
源码实现类似于:
mapped_type& operator[] (const key_type& k) { pairret = insert(make_pair(k, mapped_type())); //return (*(ret.first)).second; return ret.first->second;//返回的是第二个参数的引用,可以修改 }
mapped_type是第二个参数的类型,上面是构造的匿名对象。
可充当查找,修改,插入的功能
如果插入数据成功(返回的是插入新元素的第二个参数的引用),如果数据存在,返回的是该数据的第二个参数的引用,也可以把它修改。
举例:
void test5() { string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" }; mapcountMap; for (auto& str : arr) { countMap[str]++; } for (auto& ch : countMap) { cout << ch.first << "-" << ch.second << " "; } cout << endl; map m; m.insert(make_pair("suffer", "痛苦")); m.insert(make_pair("extend", "扩大")); m.insert(make_pair("left", "左边")); m["suffer"] = "遭受";//查找+修改 m["right"] = "右边";//插入新数据 for (auto& ch : m) { cout << ch.first << "-" << ch.second << " "; } cout << m["extend"] << endl;//查找该数据 }
结果:
3.erase等
void test6()
{
string arr[] = { "苹果", "西红柿", "苹果", "桃", "苹果", "苹果", "西瓜", "苹果", "香蕉", "苹果", "香蕉" };
map m;
for (auto& str : arr)
{
m[str]++;
}
m.erase("苹果");
for (auto& ch : m)
{
cout << ch.first << "-" << ch.second << " ";
}
}
结果:
桃-1 西瓜-1 西红柿-1 香蕉-2
其余接口与set也是类似的,这里不再叙述
4.multipmap
介绍:支持插入相同元素,其余与map是类似的,但不支持[].