unordered_map赋值以及常用成员函数

unordered_map

1. 赋值操作

赋值比较简单,和其他STL都差不多的。

#include <iostream>
#include <unordered_map>
using namespace std;
int main() 
{
    unordered_map<string, string> p1; // 直接定义
    unordered_map<string, string> p2{ {"apple", "red"}, {"lemon", "yellow"} }; // 直接在定义后赋值
    unordered_map<string, string> p3(p2); // 拷贝p2给p3
    unordered_map<string, string> p4(p3.begin(), p3.end()); // 通过迭代器一一赋值
    unordered_map<string, string> p5 = p4; // 通过赋值符号直接拷贝
    unordered_map<string, string> p6 = { {"apple", "red"}, {"lemon", "yellow"} }; // 通过赋值符号直接赋值
    system("pause");
    return 0;
}

注:后续还有可以达到赋值效果的成员函数

2. 成员函数

2.1 元素访问

1) operator[]

2) at()

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main() 
{
    unordered_map<int, string> p1 = { {1, "这是一"}, {2, "这是二"}};
    cout << "p1[1] = " << p1[1] << endl; // 通过operator[]可以直接访问该键的值
    p1[1] = "这是1"; // 在访问键的时候可以用赋值符号进行修改
    cout << "p1[1]修改后:" << p1[1] << endl;
    p1[3] = "这是三"; // 访问一个不存在的键可以直接添加键值对
    p1[4];            // 如果在访问的时候没有赋值,则只添加键,值为空
    cout << "p1[3] = " << p1[3] << endl;
    cout << "p1[4] = " << p1[4] << endl;
    cout << "p1.at(3) = " << p1.at(3) << endl; // 通过成员函数at访问键值对
    system("pause");
    return 0;
}

输出结果为:

p1[1] = 这是一
p1[1]=修改后:这是1
p1[3] = 这是三
p1[4] = 
p1.at(3) = 这是三

注:at()访问成员函数不能像[]一样对键值对进行添加,但是可以修改键所对应的值,所以[]更常用

2.2 容量

1) empty()

如果map为空,则返回true,否则返回false

2)size()

返回map中键的个数(值可以为空,但是键不可以)

3) max_size()

返回容器可用的最大值

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main() 
{
    unordered_map<int, string> p1 = { {1, "这是一"}, {2, "这是二"}, {3, "这是三"} };
    if (!p1.empty()) {
        cout << p1.size() << endl;
        cout << p1.max_size() << endl;
    }
    system("pause");
    return 0;
}

输出结果为:

3
107374182 // 不一定相同

2.3 迭代器

1) begin()

  • 返回一个迭代器,指向容器中/一个桶中的第一个元素
  • ()中不添加参数时,返回指向容器中第一个元素的迭代器,()中可填入桶数,此时返回指向该桶中第一个元素的迭代器

2) end()

  • 返回一个迭代器,指向容器中/一个桶中的最后一个元素的下一位,所以end()返回的迭代器是不指向任何元素的
  • 常用for(auto ite=map.begin();ite!=map.end();++ite)的方式循环遍历
  • 参数机制与begin的相同

3) cbegin()

  • 返回一个常量迭代器,指向容器中/一个桶中的第一个元素
  • 常量迭代器本身是可以进行加减操作的,上述的遍历方式他也可以,只是不能修改迭代器中的值,类似一个指针常量
  • 参数机制与begin相同

4) cend()

  • 返回一个常量迭代器,指向容器中/一个桶中的最后一个元素的下一位
  • 参数机制与begin相同
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main() 
{
    unordered_map<int, string> p1 = { {1, "这是一"}, {2, "这是二"}, {3, "这是三"} };
    // unordered_map<int, string>::iterator ite 可简写为 auto ite
    for (unordered_map<int, string>::iterator ite = p1.begin(); ite != p1.end(); ++ite) {
        cout << ite->first << ": " << ite->second << endl;
    }
    // 更方便的一种遍历容器的方式
    //for (auto& i : p1) {
    //    cout << i.first << ": " << i.second << endl;
    //}
    system("pause");
    return 0;
}

输出结果为:

1: 这是1
2: 这是2
3: 这是3

2.4 查看元素

1) find()

  • 参数为需要查找的键,返回该键所对应的迭代器
  • 如果未找到,则返回end()迭代器

2) count()

  • 参数为需要查找的键,返回该键出现的次数
  • 因为map的键不可重复,所以存在则返回1,不存在则返回0
  • 该函数可在unordered_multimap中返回键的个数

3) equal_range()

  • 参数为键值,返回一个满足要求的范围,具体看代码理解一下就好
#include <iostream>
#include <string>
#include <unordered_map>
#include <algorithm>
using namespace std;
int main() 
{
    unordered_map<int, string> p1 = { {1, "这是一"}, {2, "这是二"}, {3, "这是三"} };
    unordered_map<int, string> p2(p1.find(2), ++p1.find(2));
    cout << "p2中有: ";
    for (auto& i : p2) {
        cout << i.first << ": " << i.second << endl;
    }
    cout << "p1中键1的个数为: " << p1.count(1) << endl;
    cout << "p2中键1的个数为: " << p2.count(1) << endl;
    auto range = p1.equal_range(1);
    cout << "满足equal_range(1)的值为: ";
    for_each(
        range.first,
        range.second,
        [](unordered_map<int, string>::value_type& x) {cout << x.second << endl; }
    );
    system("pause");
    return 0;
}

输出结果为:

p2中有: 2: 这是二
p1中键1的个数为: 1
p2中键1的个数为: 0
满足equal_range(1)的值为: 这是一

2.5 元素修改

1) emplace()

  • 主要是用来添加或者修改一个值
  • 参数为一个键值对,若表中无该键,则直接添加进去,如果有键且有对应的值,则不改变原来的值

2) insert()

  • insert相比emplace可以插入多个值(具体看代码即可)
  • 参数可以是一个pair变量,make_pair或者直接需要加入的键值对

3) erase()

  • 用来删除表中的一个或者多个值
  • 参数为键或者迭代器都可以删除一个值,当参数为迭代器的左闭右开范围时可以删除多个值(看代码理解即可)

4) clear()

  • 清空表中所有键值对

5) swap()

  • 将两个表中的内容交换
  • 参数为另一个需要交换的map
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

int main()
{
    unordered_map<int, string> p1 = { {1, "这是一"}, {2, "这是二"}, {3, "这是三"} };
    // emplace()
    p1.emplace(1, "这是1"); // 存在则不改变
    p1.emplace(4, "这是四");// 不存在则插入
    cout << "emplace()插入后: " << endl;
    for (auto& i : p1) {
        cout << i.first << ": " << i.second << endl;
    }
    // insert()
    pair<int, string> p(5, "这是五");
    p1.insert(p); // 插入一个pair变量
    p1.insert(make_pair<int, string>(6, "这是六")); // 直接make_pair
    p1.insert({1, "这是1"}); // 直接插入(存在也不改变)
    cout << "insert()插入后: " << endl;
    for (auto& i : p1) {
        cout << i.first << ": " << i.second << endl;
    }
    // erase()
    p1.erase(1);// 直接删除键值对
    cout << "earse(1)之后:  " << endl;
    for (auto& i : p1) {
        cout << i.first << ": " << i.second << endl;
    }
    p1.erase(p1.begin());// 删除第一个迭代器的键值对
    cout << "erase(p1.begin())之后:  " << endl;
    for (auto& i : p1) {
        cout << i.first << ": " << i.second << endl;
    }
    p1.erase(p1.find(5), p1.end());// 删除从find(5)开始到end()之间的键值对
    cout << "erase(p1.find(5), p1.end()):  " << endl;
    for (auto& i : p1) {
        cout << i.first << ": " << i.second << endl;
    }
    // clear()
    p1.clear();
    cout << "clear()之后: " << endl;
    for (auto& i : p1) {
        cout << i.first << ": " << i.second << endl;
    }
    // swap()
    unordered_map<int, string> p2 = { {1, "这是1"}, {2, "这是1"}, {3, "这是1"} };
    unordered_map<int, string> p3 = { {1, "这是一"}, {2, "这是二"}, {3, "这是三"} };
    cout << "交换前p2: " << endl;
    for (auto& i : p2) {
        cout << i.first << ": " << i.second << endl;
    }
    cout << "交换前p3: " << endl;
    for (auto& i : p3) {
        cout << i.first << ": " << i.second << endl;
    }
    p2.swap(p3);
    cout << "交换后p2: " << endl;
    for (auto& i : p2) {
        cout << i.first << ": " << i.second << endl;
    }
    cout << "交换后p3: " << endl;
    for (auto& i : p3) {
        cout << i.first << ": " << i.second << endl;
    }
    system("pause");
    return 0;
}

输出结果为:

empIace()插入后:
1:这是一
2:这是二
3:这是三
4:这是四
insert()插入后:
1:这是一
2:这是二
3:这是三
4:这是四
5:这是五
6:这是六
earse(1)之后:
2:这是二
3:这是三
4:这是四
5:这是五
6:这是六
erase(p1.begin())之后:
3:这是三
4:这是四
5:这是五
6:这是六
erase(pl.find(5), p1.end())之后
3:这是三
4:这是四
clear()之后:
交换前p2:
1:这是1
2:这是1
3:这是1
交换前p3:
1:这是一
2:这是二
3:这是三
交换后p2:
1:这是一
2:这是二
3:这是三
交换后p3:
1:这是1
2:这是1
3:这是1

2.6 桶

1) buket_count()

  • 返回map当前的桶数,会根据元素的数量进行变化

2) max_buket_count()

  • 返回容量最大的桶数

3) bucket_size()

  • 参数为桶,返回桶中的元素

4) buket()

  • 参数为键,返回该键所在的桶的序号
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
int main()
{
    unordered_map<int, string> p1 = { {1, "这是一"}, {2, "这是二"}, {3, "这是三"} };
    cout << "max_bucket_count() = " << p1.max_bucket_count() << endl;
    cout << "bucket_count() = " << p1.bucket_count() << endl;
    for (unsigned i = 0; i < p1.bucket_count(); i++) {
        cout << "bucket #" << i << " contains:";
        for (auto ite = p1.begin(i); ite != p1.end(i); ite++) {
            cout << ite->first << ": " << ite->second << " ";
        }
        cout << endl;
    }
    cout << "1这个键所在的bucket的大小为: " << p1.bucket_size(p1.bucket(1)) << endl;
    system("pause");
    return 0;
}

输出结果为:

max_bucket_count() = 536870911
bucket_count() = 8
bucket #0 contains :
bucket #1 contains :
bucket #2 contains :
bucket #3 contains :
bucket #4 contains : 1 : 这是一
bucket #5 contains :
bucket #6 contains : 3 : 这是三
bucket #7 contains : 2 : 这是二
1这个键所在的bucket的大小为 :1
posted on 2022-01-12 18:20  summer_vv  阅读(1998)  评论(0编辑  收藏  举报