C++学习笔记(9)

185、pair 键值对
pair 是类模板,一般用于表示 key/value 数据,其实现是结构体。
pair 结构模板的定义如下:
template <class T1, class T2>
struct pair
{
T1 first; // 第一个成员,一般表示 key。
T2 second; // 第二个成员,一般表示 value。
pair(); // 默认构造函数。
pair(const T1 &val1,const T2 &val2); // 有两个参数的构造函数。
pair(const pair<T1,T2> &p); // 拷贝构造函数。
void swap(pair<T1,T2> &p); // 交换两个 pair。
};
make_pair 函数模板的定义如下:
template <class T1, class T2>
make_pair(const T1 &first,const T2 &second)
{
return pair<T1,T2>(first, second);
}
示例:
#include <iostream>
using namespace std;
template <class T1, class T2>
struct Pair
{
T1 first; // 第一个成员,一般表示 key。
T2 second; // 第二个成员,一般表示 value。
Pair() {
cout << "调用了有默认的构造函数。\n";
}
Pair(const T1& val1, const T2& val2) :first(val1), second(val2) {
cout << "调用了有两个参数的构造函数。\n";
}
Pair(const Pair<T1, T2>& p) : first(p.first),second(p.second) {
cout << "调用了拷贝构造函数。\n";
}
};
template <class T1, class T2>
Pair<T1, T2> make_Pair(const T1& first, const T2& second)
{
// Pair<T1, T2> p(first, second);
// return p; // 返回局部对象。
return Pair<T1, T2>(first, second); // 返回临时对象。
}
int main()
{
//pair<int, string> p0;
//cout << "p0 first=" << p0.first << ",second=" << p0.second << endl;
//pair<int, string> p1(1, "西施 1"); // 两个参数的构造函数。
//cout << "p1 first=" << p1.first << ",second=" << p1.second << endl;
//pair<int, string> p2 = p1; // 拷贝构造。
//cout << "p2 first=" << p2.first << ",second=" << p2.second << endl;
//pair<int, string> p3 = { 3, "西施 3" }; // 两个参数的构造函数。
pair<int, string> p3 { 3, "西施 3" }; // 两个参数的构造函数,省略了等于号。
//cout << "p3 first=" << p3.first << ",second=" << p3.second << endl;
auto p4 = Pair<int, string>(4, "西施 4"); // 匿名对象(显式调用构造函数)。
cout << "p4 first=" << p4.first << ",second=" << p4.second << endl;
auto p5 = make_Pair<int, string>(5, "西施 5"); // make_pair()返回的临时对象。
cout << "p5 first=" << p5.first << ",second=" << p5.second << endl;
//pair<int, string> p6 = make_pair(6, "西施 6"); // 慎用,让 make_pair()函数自动推导,再
调用拷贝构造,再隐式转换。
//cout << "p6 first=" << p6.first << ",second=" << p6.second << endl;
//auto p7 = make_pair(7, "西施 7"); // 慎用,让 make_pair()函数自动推导,再调用拷贝
构造。
//cout << "p7 first=" << p7.first << ",second=" << p7.second << endl;
//p5.swap(p4); // 交换两个 pair。
//cout << "p4 first=" << p4.first << ",second=" << p4.second << endl;
//cout << "p5 first=" << p5.first << ",second=" << p5.second << endl;
//struct st_girl
//{
// string name;
// int age;
// double height;
//};
用 pair 存放结构体数据。
//pair<int, st_girl> p = { 3,{"西施",23,48.6} };
//cout << "p first=" << p.first << endl;
//cout << "p second.name=" << p.second.name << endl;
//cout << "p second.age=" << p.second.age << endl;
//cout << "p second.height=" << p.second.height << endl;
}
186、map 容器
map 容器封装了红黑树(平衡二叉排序树),用于查找。
包含头文件: #include<map>
map 容器的元素是 pair 键值对。
map 类模板的声明:
template <class K, class V, class P = less<K>, class _Alloc = allocator<pair<const K, V >>>
class map : public _Tree<_Tmap_traits< K, V, P, _Alloc, false>>
{ …
}
第一个模板参数 K:key 的数据类型(pair.first)。
第二个模板参数 V:value 的数据类型(pair.second)。
第三个模板参数 P:排序方法,缺省按 key 升序。
第四个模板参数_Alloc:分配器,缺省用 new 和 delete。
map 提供了双向迭代器。
二叉链表:
struct BTNode
{
pair<K,V> p; // 键值对。
BTNode *parent; // 父节点。
BTNode *lchirld; // 左子树。
BTNode *rchild; // 右子树。
}; 一、构造函数
1)map(); // 创建一个空的 map 容器。
2)map(initializer_list<pair<K,V>> il); // 使用统一初始化列表。
3)map(const map<K,V>& m); // 拷贝构造函数。
4)map(Iterator first, Iterator last); // 用迭代器创建 map 容器。
5)map(map<K,V>&& m); // 移动构造函数(C++11 标准)。
示例:
#include <iostream>
#include <map>
using namespace std;
int main()
{
// 1)map(); // 创建一个空的 map 容器。
map<int, string> m1;
// 2)map(initializer_list<pair<K, V>> il); // 使用统一初始化列表。
map<int, string> m2( { { 8,"冰冰" }, { 3,"西施" }, { 1,"幂幂" }, { 7,"金莲" }, { 5,"西瓜" } } );
// map<int, string> m2={ { 8,"冰冰" }, { 3,"西施" }, { 1,"幂幂" }, { 7,"金莲" }, { 5,"西瓜" } };
// map<int, string> m2 { { 8,"冰冰" }, { 3,"西施" }, { 1,"幂幂" }, { 7,"金莲" }, { 5,"西瓜" } };
for (auto& val : m2)
cout << val.first << "," << val.second << " ";
cout << endl;
// 3)map(const map<K, V>&m); // 拷贝构造函数。
map<int, string> m3 = m2;
for (auto& val : m3)
cout << val.first << "," << val.second << " ";
cout << endl;
// 4)map(Iterator first, Iterator last); // 用迭代器创建 map 容器。
auto first = m3.begin(); first++;
auto last = m3.end(); last--;
map<int, string> m4(first,last);
for (auto& val : m4)
cout << val.first << "," << val.second << " ";
cout << endl;
// 5)map(map<K, V> && m); // 移动构造函数(C++11 标准)。
}
二、特性操作
size_t size() const; // 返回容器的实际大小(已使用的空间)。
bool empty() const; // 判断容器是否为空。
void clear(); // 清空容器。 三、元素操作
V &operator[](K key); // 用给定的 key 访问元素。
const V &operator[](K key) const; // 用给定的 key 访问元素,只读。
V &at(K key); // 用给定的 key 访问元素。
const V &at(K key) const; // 用给定的 key 访问元素,只读。
注意:
1)[ ]运算符:如果指定键不存在,会向容器中添加新的键值对;如果指定键不存在,则读取或修改
容器中指定键的值。
2)at()成员函数:如果指定键不存在,不会向容器中添加新的键值对,而是直接抛出 out_of_range
异常。
示例:
#include <iostream>
#include <map>
using namespace std;
int main()
{
map<string, string> m( { { "08","冰冰" }, { "03","西施" }, { "01","幂幂" }, { "07","金莲" }, { "05","西瓜" } } );
cout << "m[08]=" << m["08"] << endl; // 显示 key 为 08 的元素的 value。
cout << "m[09]=" << m["09"] << endl; // 显示 key 为 09 的元素的 value。key 为 09 的
元素不存在,将添加新的键值对。
m["07"] = "花花"; // 把 key 为 07 的元素的
value 修改为花花。
m["12"] = "小乔"; // 将添加新的键值对。
for (auto& val : m)
cout << val.first << "," << val.second << " ";
cout << endl;
}
四、赋值操作
给已存在的容器赋值,将覆盖容器中原有的内容。
1)map<K,V> &operator=(const map<K,V>& m); // 把容器 m 赋值给当前容器。
2)map<K,V> &operator=(initializer_list<pair<K,V>> il); // 用统一初始化列表给当前容器赋
值。五、交换操作
void swap(map<K,V>& m); // 把当前容器与 m 交换。
交换的是树的根结点。 六、比较操作
bool operator == (const map<K,V>& m) const;
bool operator != (const map<K,V>& m) const;
七、查找操作
1)查找键值为 key 的键值对
在 map 容器中查找键值为 key 的键值对,如果成功找到,则返回指向该键值对的迭代器;失败返回
end()。
iterator find(const K &key);
const_iterator find(const K &key) const; // 只读。
2)查找键值>=key 的键值对
在 map 容器中查找第一个键值>=key 的键值对,成功返回迭代器;失败返回 end()。
iterator lower_bound(const K &key);
const_iterator lower_bound(const K &key) const; // 只读。
3)查找键>key 的键值对
在 map 容器中查找第一个键值>key 的键值对,成功返回迭代器;失败返回 end()。
iterator upper_bound(const K &key);
const_iterator upper_bound(const K &key) const; // 只读。
4)统计键值对的个数
统计 map 容器中键值为 key 的键值对的个数。
size_t count(const K &key) const;
示例:
#include <iostream>
#include <map>
using namespace std;
int main()
{
map<string, string> m( { { "08","冰冰" }, { "03","西施" }, { "01","幂幂" }, { "07","金莲" }, { "05","西瓜" } } );
for (auto& val : m)
cout << val.first << "," << val.second << " ";
cout << endl;
// 在 map 容器中查找键值为 key 的键值对,如果成功找到,则返回指向该键值对的迭代器;失
败返回 end()。
auto it1 = m.find("05");
if (it1 != m.end())
cout << "查找成功:" << it1->first << "," << it1->second << endl;
else
cout << "查找失败。\n";
// 在 map 容器中查找第一个键值 >= key 的键值对,成功返回迭代器;失败返回 end()。
auto it2 = m.lower_bound("05");
if (it2 != m.end())
cout << "查找成功:" << it2->first << "," << it2->second << endl;
else
cout << "查找失败。\n";
// 在 map 容器中查找第一个键值 > key 的键值对,成功返回迭代器;失败返回 end()。
auto it3 = m.upper_bound("05");
if (it3 != m.end())
cout << "查找成功:" << it3->first << "," << it3->second << endl;
else
cout << "查找失败。\n";
// 统计 map 容器中键值为 key 的键值对的个数。
cout << "count(05)=" << m.count("05") << endl; // 返回 1。
cout << "count(06)=" << m.count("06") << endl; // 返回 0。
}
八、插入和删除
1)void insert(initializer_list<pair<K,V>> il); // 用统一初始化列表在容器中插入多个元素。
2)pair<iterator,bool> insert(const pair<K,V> &value); // 在容器中插入一个元素,返回值 pair:
first 是已插入元素的迭代器,second 是插入结果。
3)void insert(iterator first,iterator last); // 用迭代器插入一个区间的元素。
4)pair<iterator,bool> emplace (...); // 将创建新键值对所需的数据作为参数直接传入,map 容
器将直接构造元素。返回值 pair:first 是已插入元素的迭代器,second 是插入结果。
例:mm.emplace(piecewise_construct, forward_as_tuple(8), forward_as_tuple("冰冰", 18));
5)iterator emplace_hint (const_iterator pos,...); // 功能与第 4)个函数相同,第一个参数提示插
入位置,该参数只有参考意义,如果提示的位置是正确的,对性能有提升,如果提示的位置不正确,性能
反而略有下降,但是,插入是否成功与该参数元关。该参数常用 end()和 begin()。成功返回新插入元素
的迭代器;如果元素已经存在,则插入失败,返回现有元素的迭代器。
6)size_t erase(const K & key); // 从容器中删除指定 key 的元素,返回已删除元素的个数。
7)iterator erase(iterator pos); // 用迭代器删除元素,返回下一个有效的迭代器。
8)iterator erase(iterator first,iterator last); // 用迭代器删除一个区间的元素,返回下一个有效
的迭代器。
示例:
#include <iostream>
#include <map>
using namespace std;
class CGirl // 超女类。
{
public:
string m_name; // 超女姓名。
int m_age; // 超女年龄。
/*CGirl() : m_age(0) {
cout << "默认构造函数。\n";
}*/
CGirl(const string name, const int age) : m_name(name), m_age(age) {
cout << "两个参数的构造函数。\n";
}
CGirl(const CGirl & g) : m_name(g.m_name), m_age(g.m_age) {
cout << "拷贝构造函数。\n";
}
};
int main()
{
//map<int, CGirl> mm;
//mm.insert (pair<int, CGirl>(8, CGirl("冰冰", 18))); // 一次构造函数,
两次拷贝构造函数。
//mm.insert (make_pair<int, CGirl>(8, CGirl("冰冰", 18))); // 一次构造函数,两次
拷贝构造函数。
//mm.emplace(pair<int, CGirl>(8, CGirl("冰冰", 18))); // 一次构造函数,两
次拷贝构造函数。
//mm.emplace(make_pair<int, CGirl>(8, CGirl("冰冰", 18))); // 一次构造函数,两次拷
贝构造函数。
//mm.emplace(8, CGirl("冰冰", 18)); // 一
次构造函数,一次拷贝构造函数。
//mm.emplace(8, " 冰 冰 ", 18);
// 错误。
//mm.emplace(piecewise_construct, forward_as_tuple(8), forward_as_tuple("冰冰", 18));
// 一次构造函数。
//for (const auto& val : mm)
// cout << val.first << "," << val.second.m_name << "," << val.second.m_name << "
";
//cout << endl;
//return 0;
map<int, string> m;
// 1)void insert(initializer_list<pair<K,V>> il); // 用统一初始化列表在容器中插入多个元素。
m.insert({ { 8,"冰冰" }, { 3,"西施" }});
m.insert({ pair<int,string>(1,"幂幂"), make_pair<int,string>(7,"金莲"), {5,"西瓜"}});
m.insert({ { 18,"冰冰" }, { 3,"西施" } });
// 2)pair<iterator,bool> insert(const pair<K,V> &value);
// 在容器中插入一个元素,返回值 pair:first 是已插入元素的迭代器,second 是插入结果。
auto ret = m.insert(pair<int, string>(18, "花花"));
if (ret.second == true) cout << "插入成功:" << ret.first->first << "," << ret.first->second
<< endl;
else cout << "插入失败。\n";
// 3)void insert(iterator first, iterator last); // 用迭代器插入一个区间的元素。
// 4)pair<iterator, bool> emplace(...);
// 将创建新键值对所需的数据作为参数直接传入,map 容器将直接构造元素。
// 返回值 pair:first 是已插入元素的迭代器,second 是插入结果。
auto ret1 = m.emplace(20, "花花");
if (ret1.second == true) cout << " 插 入 成 功 : " << ret1.first->first << "," <<
ret1.first->second << endl;
else cout << "插入失败。\n";
// 5)iterator emplace_hint(const_iterator pos, ...);
// 功能与第 4)个函数相同,第一个参数提示插入位置,该参数只有参考意义,如果提示的位置
是正确的,
// 对性能有提升,如果提示的位置不正确,性能反而略有下降,但是,插入是否成功与该参数
元关。
// 该参数常用 end()和 begin()。成功返回新插入元素的迭代器;如果元素已经存在,则插入失
败,返回现
// 有元素的迭代器。
m.emplace_hint(m.begin(), piecewise_construct, forward_as_tuple(23), forward_as_tuple("冰棒"));
for (auto& val : m)
cout << val.first << "," << val.second << " ";
cout << endl;
}
187、unordered_map 容器
unordered_map 容器封装了哈希表,查找、插入和删除元素时,只需要比较几次 key 的值。
包含头文件: #include<unordered_map>
unordered_map 容器的元素是 pair 键值对。
unordered_map 类模板的声明:
template <class K, class V, class _Hasher = hash<K>, class _Keyeq = equal_to<K>, class _Alloc = allocator<pair<const K, V>>>
class unordered_map : public _Hash<_Umap_traits<K, V, _Uhash_compare<K, _Hasher,
_Keyeq>, _Alloc, false>>
{ …
}
第一个模板参数 K:key 的数据类型(pair.first)。
第二个模板参数 V:value 的数据类型(pair.second)。
第三个模板参数_Hasher:哈希函数,默认值为 std::hash<K>
第四个模板参数_Keyeq:比较函数,用于判断两个 key 是否相等,默认值是 std::equal_to<K>。
第五个模板参数_Alloc:分配器,缺省用 new 和 delete。
创建 std::unordered_map 类模板的别名:
template<class K,class V>
using umap = std::unordered_map<K, V>; 一、构造函数
1)umap(); // 创建一个空的 umap 容器。
2)umap(size_t bucket); // 创建一个空的 umap 容器,指定了桶的个数,下同。
3)umap(initializer_list<pair<K,V>> il); // 使用统一初始化列表。
4)umap(initializer_list<pair<K,V>> il, size_t bucket); // 使用统一初始化列表。
5)umap(Iterator first, Iterator last); // 用迭代器创建 umap 容器。
6)umap(Iterator first, Iterator last, size_t bucket); // 用迭代器创建 umap 容器。
7)umap(const umap<K,V>& m); // 拷贝构造函数。
8)umap(umap<K,V>&& m); // 移动构造函数(C++11 标准)。
示例:
#include <iostream>
#include <unordered_map>
using namespace std;
template<class K, class V>
using umap = std::unordered_map<K, V>;
int main()
{
// 1)umap(); // 创建一个空的 map 容器。
umap<int, string> m1;
// 2)umap(initializer_list<pair<K, V>> il); // 使用统一初始化列表。
umap<int, string> m2({ { 8,"冰冰" }, { 3,"西施" }, { 1,"幂幂" }, { 7,"金莲" }, { 5,"西瓜" } });
// umap<int, string> m2={ { 8,"冰冰" }, { 3,"西施" }, { 1,"幂幂" }, { 7,"金莲" }, { 5,"西瓜" } };
// umap<int, string> m2 { { 8,"冰冰" }, { 3,"西施" }, { 1,"幂幂" }, { 7,"金莲" }, { 5,"西瓜" } };
for (auto& val : m2)
cout << val.first << "," << val.second << " ";
cout << endl;
// 3)umap(const map<K, V>&m); // 拷贝构造函数。
umap<int, string> m3 = m2;
for (auto& val : m3)
cout << val.first << "," << val.second << " ";
cout << endl;
// 4)umap(Iterator first, Iterator last); // 用迭代器创建 map 容器。
auto first = m3.begin(); first++;
auto last = m3.end(); last--;
umap<int, string> m4(first, last);
for (auto& val : m4)
cout << val.first << "," << val.second << " ";
cout << endl;
// 5)umap(map<K, V> && m); // 移动构造函数(C++11 标准)。
}
二、特性操作
1)size_t size() const; // 返回容器中元素的个数。
2)bool empty() const; // 判断容器是否为空。
3)void clear(); // 清空容器。
4)size_t max_bucket_count(); // 返回容器底层最多可以使用多少桶,无意义。
5)size_t bucket_count(); // 返回容器桶的数量,空容器有 8 个桶。
6)float load_factor(); // 返回容器当前的装填因子,load_factor() = size() / bucket_count()。
7)float max_load_factor(); // 返回容器的最大装填因子,达到该值后,容器将扩充,缺省
为 1。
8)void max_load_factor (float z ); // 设置容器的最大装填因子。
9)iterator begin(size_t n); // 返回第 n 个桶中第一个元素的迭代器。
10)iterator end(size_t n); // 返回第 n 个桶中最后一个元素尾后的迭代器。
11)void reserve(size_t n); // 将容器设置为至少 n 个桶。
12)void rehash(size_t n); // 将桶的数量调整为>=n。如果 n 大于当前容器的桶数,
该方法会将容器重新哈希;如果 n 的值小于当前容器的桶数,该方法可能没有任何作用。
13)size_t bucket_size(size_t n); // 返回第 n 个桶中元素的个数,0 <= n < bucket_count()。
14)size_t bucket(K &key); // 返回值为 key 的元素对应的桶的编号。 三、元素操作
V &operator[](K key); // 用给定的 key 访问元素。
const V &operator[](K key) const; // 用给定的 key 访问元素,只读。
V &at(K key); // 用给定的 key 访问元素。
const V &at(K key) const; // 用给定的 key 访问元素,只读。
注意:
1)[ ]运算符:如果指定键不存在,会向容器中添加新的键值对;如果指定键不存在,则读取或修改
容器中指定键的值。
2)at()成员函数:如果指定键不存在,不会向容器中添加新的键值对,而是直接抛出 out_of_range
异常。
示例:
#include <iostream>
#include <unordered_map>
using namespace std;
template<class K, class V>
using umap = std::unordered_map<K, V>;
int main()
{
umap<string, string> m( { { "08","冰冰" }, { "03","西施" }, { "01","幂幂" }, { "07","金莲" }, { "05","西瓜" } } );
cout << "m[08]=" << m["08"] << endl; // 显示 key 为 08 的元素的 value。
cout << "m[09]=" << m["09"] << endl; // 显示 key 为 09 的元素的 value。key 为 09 的
元素不存在,将添加新的键值对。
m["07"] = "花花"; // 把 key 为 07 的元素的
value 修改为花花。
m["12"] = "小乔"; // 将添加新的键值对。
for (auto& val : m)
cout << val.first << "," << val.second << " ";
cout << endl;
}
四、赋值操作
给已存在的容器赋值,将覆盖容器中原有的内容。
1)umap<K,V> &operator=(const umap<K,V>& m); // 把容器 m 赋值给当前容器。
2)umap<K,V> &operator=(initializer_list<pair<K,V>> il); // 用统一初始化列表给容器赋值。 五、交换操作
void swap(umap<K,V>& m); // 把当前容器与 m 交换。
交换的是树的根结点。
六、比较操作
bool operator == (const umap<K,V>& m) const;
bool operator != (const umap<K,V>& m) const;
七、查找操作
1)查找键值为 key 的键值对
在 umap 容器中查找键值为 key 的键值对,如果成功找到,则返回指向该键值对的迭代器;失败返
回 end()。
iterator find(const K &key);
const_iterator find(const K &key) const; // 只读。
2)统计键值对的个数
统计 umap 容器中键值为 key 的键值对的个数。
size_t count(const K &key) const;
示例:
八、插入和删除
1)void insert(initializer_list<pair<K,V>> il); // 用统一初始化列表在容器中插入多个元素。
2)pair<iterator,bool> insert(const pair<K,V> &value); // 在容器中插入一个元素,返回值 pair:
first 是已插入元素的迭代器,second 是插入结果。
3)void insert(iterator first,iterator last); // 用迭代器插入一个区间的元素。
4)pair<iterator,bool> emplace (...); // 将创建新键值对所需的数据作为参数直接传入,map 容
器将直接构造元素。返回值 pair:first 是已插入元素的迭代器,second 是插入结果。
例:mm.emplace(piecewise_construct, forward_as_tuple(8), forward_as_tuple("冰冰", 18));
5)iterator emplace_hint (const_iterator pos,...); // 功能与第 4)个函数相同,第一个参数提示插
入位置,该参数只有参考意义。对哈希容器来说,此函数意义不大。
6)size_t erase(const K & key); // 从容器中删除指定 key 的元素,返回已删除元素的个数。
7)iterator erase(iterator pos); // 用迭代器删除元素,返回下一个有效的迭代器。
8)iterator erase(iterator first,iterator last); // 用迭代器删除一个区间的元素,返回下一个有效
的迭代器。
示例:
#include <iostream>
#include <unordered_map>
using namespace std;
template<class K, class V>
using umap = std::unordered_map<K, V>;
class CGirl // 超女类。
{
public:
string m_name; // 超女姓名。
int m_age; // 超女年龄。
/*CGirl() : m_age(0) {
cout << "默认构造函数。\n";
}*/
CGirl(const string name, const int age) : m_name(name), m_age(age) {
cout << "两个参数的构造函数。\n";
}
CGirl(const CGirl& g) : m_name(g.m_name), m_age(g.m_age) {
cout << "拷贝构造函数。\n";
}
};
int main()
{
//umap<int, CGirl> mm;
mm.insert (pair<int, CGirl>(8, CGirl("冰冰", 18))); // 一次构造函
数,两次拷贝构造函数。
mm.insert (make_pair<int, CGirl>(8, CGirl("冰冰", 18))); // 一次构造函数,两
次拷贝构造函数。
mm.emplace(pair<int, CGirl>(8, CGirl("冰冰", 18))); // 一次构造函数,
两次拷贝构造函数。
mm.emplace(make_pair<int, CGirl>(8, CGirl("冰冰", 18))); // 一次构造函数,两次
拷贝构造函数。
mm.emplace(8, CGirl("冰冰", 18)); // 一次构造函数,一次拷贝构造函数。
// mm.emplace(8, " 冰 冰 ", 18);
// 错误。
//mm.emplace(piecewise_construct, forward_as_tuple(8), forward_as_tuple("冰冰", 18));
// 一次构造函数。
//for (const auto& val : mm)
// cout << val.first << "," << val.second.m_name << "," << val.second.m_name << "
";
//cout << endl;
//return 0;
umap<int, string> m;
// 1)void insert(initializer_list<pair<K,V>> il); // 用统一初始化列表在容器中插入多个元素。
m.insert({ { 8,"冰冰" }, { 3,"西施" } });
m.insert({ pair<int,string>(1,"幂幂"), make_pair<int,string>(7,"金莲"), {5,"西瓜"} });
m.insert({ { 18,"冰冰" }, { 3,"西施" } });
// 2)pair<iterator,bool> insert(const pair<K,V> &value);
// 在容器中插入一个元素,返回值 pair:first 是已插入元素的迭代器,second 是插入结果。
auto ret = m.insert(pair<int, string>(18, "花花"));
if (ret.second == true) cout << "插入成功:" << ret.first->first << "," << ret.first->second
<< endl;
else cout << "插入失败。\n";
// 3)void insert(iterator first, iterator last); // 用迭代器插入一个区间的元素。
// 4)pair<iterator, bool> emplace(...);
// 将创建新键值对所需的数据作为参数直接传入,umap 容器将直接构造元素。
// 返回值 pair:first 是已插入元素的迭代器,second 是插入结果。
auto ret1 = m.emplace(20, "花花");
if (ret1.second == true) cout << " 插 入 成 功 : " << ret1.first->first << "," <<
ret1.first->second << endl;
else cout << "插入失败。\n";
// 5)iterator emplace_hint(const_iterator pos, ...);
m.emplace_hint(m.begin(), piecewise_construct, forward_as_tuple(23), forward_as_tuple("冰棒"));
for (auto& val : m)
cout << val.first << "," << val.second << " ";
cout << endl;
}
188、queue 容器
queue 容器的逻辑结构是队列,物理结构可以是数组或链表,主要用于多线程之间的数据共享。
包含头文件: #include<queue>
queue 类模板的声明:
template <class T, class _Container = deque<T>>
class queue{ ……
}
第一个模板参数 T:元素的数据类型。
第二个模板参数_Container:底层容器的类型,缺省是 std::deque,可以用 std::list,还可以用自定
义的类模板。
queue 容器不支持迭代器。 一、构造函数
1)queue(); // 创建一个空的队列。
2)queue(const queue<T>& q); // 拷贝构造函数。
3)queue(queue<T>&& q); // 移动构造函数(C++11 标准)。
析构函数~queue()释放内存空间。 二、常用操作
1)void push(const T& value); // 元素入队。
2)void emplace(…); // 元素入队,…用于构造元素。C++11
3)size_t size() const; // 返回队列中元素的个数。
4)bool empty() const; // 判断队列是否为空。
5)T &front(); // 返回队头元素。
6)const T &front(); // 返回队头元素,只读。
7)T &back(); // 返回队尾元素。
8)const T &back(); // 返回队头元素,只读。
9)void pop(); // 出队,删除队头的元素。
示例:
#include <iostream>
#include <queue>
#include <deque>
#include <list>
using namespace std;
class girl // 超女类。
{
public:
int m_bh; // 编号。
string m_name; // 姓名。
girl(const int& bh, const string& name) : m_bh(bh), m_name(name) {}
};
int main()
{
// template <class T, class _Container = deque<T>>
// class queue {
// ……
// }
// 第一个模板参数 T:元素的数据类型。
// 第二个模板参数_Container:底层容器的类型,缺省是 std::deque,可以用 std::list,还可以
用自定义的类模板。
queue<girl, list<girl>> q; // 物理结构为链表。
//queue<girl, deque<girl>> q; // 物理结构为数组。
//queue<girl> q; // 物理结构为数组。
//queue<girl, vector<girl>> q; // 物理结构为 vector,不可以。
q.push(girl(3, "西施")); // 效率不高。
q.emplace(8, "冰冰"); // 效率更高。
q.push(girl(5, "幂幂"));
q.push(girl(2, "西瓜"));
while (q.empty() == false)
{
cout << "编号:" << q.front().m_bh << ",姓名:" << q.front().m_name << endl;
q.pop();
}
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值