map的使用(C++)

简介: map的使用(C++)

map的使用

简介:map是C++的STL中最常用的容器之一,他对于算法题的在算法题与工程项目中的贡献难以替代,本文旨在快速让读者入门map的使用,附带英文解说。

map/multimap的基本概念(它们都是同一个头文件)

注意:Python里面的字典就是这么造出来的.

insert函数仔细看,里面的参数是pair,然后通过输出可以看出,元素按照对组的key值进行排序,也就是first值。

multimap除了允许重复的key值以外其他的和map一样

Note: This is how the dictionary in Python is made
If you look at the insert function carefully, the parameters in it are "pair". Then you can see from the output that the elements are sorted according to the key value of the group, that is the "first" value.
multimap is the same as map except for duplicate key values
#include<iostream>
#include<map>
using namespace std;
/* map container construction and assignment*/
void PrintMap(map<int, int>& m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
}
void test01()
{
  // Create map container
  // Default construction
  map<int, int>m;
  m.insert(pair<int, int>(2, 10));
  m.insert(pair<int, int>(1, 120));
  m.insert(pair<int, int>(4, 100));
  m.insert(pair<int, int>(3, 400));
  cout << "m: " << endl;
  PrintMap(m);
  cout << endl;
  // Copy construction
  map<int, int>m2(m);
  cout << "m2: " << endl;
  PrintMap(m2);
  cout << endl;
  // Assignment
  map<int, int>m3;
  m3 = m2;
  cout << "m3: " << endl;
  PrintMap(m3);
}![请添加图片描述](https://ucc.alicdn.com/images/user-upload-01/c908bff8207945d69e4a33cec10e454e.jpeg)
void test02()
{
  multimap<int, string>mm;
  mm.insert(pair<int, string>(2, "刘备"));
  mm.insert(pair<int, string>(1, "小明"));
  mm.insert(pair<int, string>(5, "宋神宗"));
  mm.insert(pair<int, string>(2, "李斯"));
  mm.insert(pair<int, string>(8, "曹操"));
  mm.insert(pair<int, string>(1, "路飞"));
  cout << "mm: " << endl;
  for (multimap<int, string>::iterator it = mm.begin(); it != mm.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
}
int main()
{
  test01();
  cout << endl << "---------------------" << endl;
  test02();
  return 0;
}

运行结果:

map大小和交换

注意:swap函数目前来看只支持相同数据类型的集合之间的交换

Note: at present, swap function only supports exchange between sets of the same data type
#include<iostream>
#include<map>
#include<string>
using namespace std;
/* map container size and swap*/
void PrintMap(map<int, int>& m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
}
void PrintMap(map<string, int>& m)
{
  for (map<string, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
}
void test01()
{
  // Create map container
  map<int, int>m;
  m.insert(pair<int, int>(2, 10));
  m.insert(pair<int, int>(1, 120));
  m.insert(pair<int, int>(4, 100));
  m.insert(pair<int, int>(3, 400));
  if (m.empty())
  {
    cout << "m为空" << endl;
  }
  else
  {
    cout << "m不为空" << endl;
    cout << "m的大小:" << m.size() << endl;
  }
  cout << endl;
  cout << "交换前: " << endl;
  cout << "m: " << endl;
  PrintMap(m);
  cout << endl;
  map<string, int>m2;
  m2.insert(pair<string, int>("玄德", 12));
  m2.insert(pair<string, int>("玄德", 23));
  m2.insert(pair<string, int>("张飞", 4));
  m2.insert(pair<string, int>("关于", 1));
  m2.insert(pair<string, int>("曹操", 2));
  m2.insert(pair<string, int>("张建", 5));
  m2.insert(pair<string, int>("皓一", 6));
  // string 字符串如果是中文的话,应该是按照汉字的编码表来排序的,但是汉字的编码表不止一张,这些之后再讨论
  cout << "m2: " << endl;
  PrintMap(m2);
  cout << endl;
  map<int, int>m3;
  m3.insert(pair<int, int>(12, 12));
  m3.insert(pair<int, int>(9, 23));
  m3.insert(pair<int, int>(5, 4));
  m3.insert(pair<int, int>(4, 1));
  m3.insert(pair<int, int>(3, 2));
  m3.insert(pair<int, int>(45, 5));
  m3.insert(pair<int, int>(1, 6));
  cout << "m3: " << endl;
  PrintMap(m3);
  cout << endl;
  cout << "------------------------" << endl;
  cout << "交换后:" << endl;
  // m.swap(m2);  // 这里可以看见, swap函数只支持相同类型的map容器之间的交换
  m.swap(m3);
  cout << "m: " << endl;
  PrintMap(m);
  cout << endl;
  cout << "m3: " << endl;
  PrintMap(m3);
  cout << endl;
}
int main()
{
  test01();
  return 0;
}

运行结果:

map插入和删除

注意:第三种插入方式太长不建议使用,第四种方式虽然看起来简短但是也不建议使用,这个括号[]的目的不是用来设置元素的,用于设置元素的话,容易导致混乱,后面的一个例子会说明。

[]主要是用来访问的,当我们确定这个key的值的时候我们就可以通过key来访问,key对应的值。

Note: the third insertion method is too long and is not recommend. Although the fourth insertion method looks short, it is not recommended. The purpose of this [] is not to set
elements. If it is used to set elements, it will easily lead to confusion. A later example will illustrate.
When we determine the value of the key, we can access the corresponding value of the key through the key.

第一种情况:

#include<iostream>
#include<map>
#include<string>
using namespace std;
/* map container insertion and deletion*/
void PrintMap(map<int, int>& m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
}
void test01()
{
  // Create map container
  map<int, int>m;
  // insert
  // The first method 
  m.insert(pair<int, int>(1, 10));
  // The second method
  m.insert(make_pair(2, 20));
  // The third method 
  m.insert(map<int, int>::value_type(3, 30));
  // The fourth mathod
  m[4] = 40;
  cout << "m[5] = ";
  cout << m[5] << endl;
  cout << "m[6] = ";
  cout << m[6] << endl;
  // 这两处位置就体现了一个问题,明明在插入的时候没有插入m[5], m[6]但是在打印的时候这两个却可以打印出来
  // 而且后面的PrintMap也将这个两个打印出来了
  // 这里要说明的是如果没有插入m[n],是可以输出这个m[n]的,但是它的值为0
  cout << endl << "m: " << endl;
  PrintMap(m);
}
int main()
{
  test01();
  return 0;
}

运行结果:

第二种情况:

#include<iostream>
#include<map>
#include<string>
using namespace std;
/* map container insertion and deletion*/
void PrintMap(map<int, int>& m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
}
void test01()
{
  // Create map container
  map<int, int>m;
  // insert
  // The first method 
  m.insert(pair<int, int>(1, 10));
  // The second method
  m.insert(make_pair(2, 20));
  // The third method 
  m.insert(map<int, int>::value_type(3, 30));
  // The fourth mathod
  // m[4] = 40;  把这里的m[4]给注释了之后,在这个容器中就没有了这个值,然后打印的时候就不会出现这个值
          // 及时是PrintMap的打印,这一体现出了map容器的元素的存储在空间上也不是连续的
  cout << "m[5] = ";
  cout << m[5] << endl;
  cout << "m[6] = ";
  cout << m[6] << endl;
  // 这两处位置就体现了一个问题,明明在插入的时候没有插入m[5], m[6]但是在打印的时候这两个却可以打印出来
  // 而且后面的PrintMap也将这个两个打印出来了
  // 这里要说明的是如果没有插入m[n],是可以输出这个m[n]的,但是它的值为0
  cout << endl << "m: " << endl;
  PrintMap(m);
}
int main()
{
  test01();
  return 0;
}

运行结果:

#include<iostream>
#include<map>
#include<string>
using namespace std;
/* map container insertion and deletion*/
void PrintMap(map<int, int>& m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
}
void test01()
{
  // Create map container
  map<int, int>m;
  // insert
  // The first method 
  m.insert(pair<int, int>(1, 10));
  // The second method
  m.insert(make_pair(2, 20));
  // The third method 
  m.insert(map<int, int>::value_type(3, 30));
  // The fourth mathod
  m[4] = 40; 
  // []不建议插入,用途 可以利用key访问到value
  // cout << m[4]<< endl;
  cout << endl << "m: " << endl;
  PrintMap(m);
  cout << endl;
  // erase
  m.erase(m.begin());  // Through iterator
  cout << endl << "m: " << endl;
  PrintMap(m);
  cout << endl;
  m.erase(3);  // Through value
  cout << endl << "m: " << endl;
  PrintMap(m);
  cout << endl;
  m.erase(m.begin(), m.end());  // 等价于m.clear();
  cout << endl << "m: " << endl;
  PrintMap(m);
  cout << endl;
}
int main()
{
  test01();
  return 0;
}

运行结果:

map查找和统计

注意:find返回的迭代器,不是具体位置,将find的结果打印出来的话就是这个值。

在map中count就只有0或者1,multimap允许重复key值里面有多种结果。

Note: the iterator returned by find function is not the specific location. If the result of find function is printed out, it is this value.
In map, count is only 0 or 1, and multimap allows mulitimap results in repeated key values.
#include<iostream>
#include<map>
#include<string>
using namespace std;
/* map container find and count*/
void PrintMap(map<int, int>& m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
}
void test01()
{
  // Create map container
  map<int, int>m;
  m.insert(make_pair(1, 10));
  m.insert(pair<int, int>(2, 20));
  m.insert(map<int, int>::value_type(3, 30));
  m[4] = 40;
  m[4] = 40;
  m[4] = 40;
  m[4] = 40;
  map<int, int>::iterator pos = m.find(2);
  if (pos != m.end())
  {
    cout << "找到这个元素 key = " << pos->first << "  value = "<< pos->second <<endl;
  }
  else
  {
    cout << "未找到这个元素" << endl;
  }
  cout << endl;
  int num = m.count(4);
  // num = 1, map 不允许插入重复的元素
  cout << "num = " << num << endl;
}
int main()
{
  test01();
  return 0;
}

运行结果:

总结:

map容器排序

#include<iostream>
#include<map>
#include<string>
using namespace std;
/* map sort*/
class Mycmp  // 这个就是仿函数   
{
public:
  bool operator()(int m1, int m2) const
  {
    // 降序
    return m1 > m2;
  }
};
void PrintMap(map<int, int>& m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
}
void test01()
{
  // Create map container
  map<int, int>m;
  m.insert(make_pair(1, 10));
  m.insert(make_pair(2, 20));
  m.insert(make_pair(3, 30));
  m.insert(make_pair(4, 40));
  m.insert(make_pair(5, 50));
  cout << "m: " << endl;
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
  map<int, int, Mycmp>m2;  // 仿函数必须在定义的时候使用,已经定义好了的,排序规则不可              // 改变
  m2.insert(make_pair(1, 10));
  m2.insert(make_pair(2, 20));
  m2.insert(make_pair(3, 30));
  m2.insert(make_pair(4, 40));
  m2.insert(make_pair(5, 50));
  cout << "m2: " << endl;
  for (map<int, int, Mycmp>::iterator it = m2.begin(); it != m2.end(); it++)
  {
    cout << "key = " << it->first << "  value = " << it->second << endl;
  }
  cout << endl;
}
int main()
{
  test01();
  return 0;
}

运行结果:

如果大家觉得有用的话,可以关注我下面的微信公众号,极客李华,我会在里面更新更多行业资讯,企业面试内容,编程资源,如何写出可以让大厂面试官眼前一亮的简历等内容,让大家更好学习编程,我的抖音,B站也叫极客李华。大家喜欢也可以关注一下

如果大家觉得有用的话,可以关注我下面的微信公众号,极客李华,我会在里面更新更多行业资讯,企业面试内容,编程资源,如何写出可以让大厂面试官眼前一亮的简历等内容,让大家更好学习编程,我的抖音,B站也叫极客李华。大家喜欢也可以关注一下

相关文章
|
6月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
173 2
|
6月前
|
存储 算法 C++
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
333 73
|
10月前
|
存储 C++ 容器
【C++】map、set基本用法
本文介绍了C++ STL中的`map`和`set`两种关联容器。`map`用于存储键值对,每个键唯一;而`set`存储唯一元素,不包含值。两者均基于红黑树实现,支持高效的查找、插入和删除操作。文中详细列举了它们的构造方法、迭代器、容量检查、元素修改等常用接口,并简要对比了`map`与`set`的主要差异。此外,还介绍了允许重复元素的`multiset`和`multimap`。
238 3
【C++】map、set基本用法
|
10月前
|
存储 算法 C++
【C++】unordered_map(set)
C++中的`unordered`容器(如`std::unordered_set`、`std::unordered_map`)基于哈希表实现,提供高效的查找、插入和删除操作。哈希表通过哈希函数将元素映射到特定的“桶”中,每个桶可存储一个或多个元素,以处理哈希冲突。主要组成部分包括哈希表、哈希函数、冲突处理机制、负载因子和再散列,以及迭代器。哈希函数用于计算元素的哈希值,冲突通过开链法解决,负载因子控制哈希表的扩展。迭代器支持遍历容器中的元素。`unordered_map`和`unordered_set`的插入、查找和删除操作在理想情况下时间复杂度为O(1),但在冲突较多时可能退化为O(n)。
200 5
|
10月前
|
存储 C++ 容器
【C++】map的模拟实现
C++中的`map`是STL中的一种关联容器,存储键值对且键唯一。`map`基于红黑树实现,自动按键排序,支持动态调整、复杂数据类型、丰富的成员函数及双向迭代器。插入、查找等操作保证了对数时间复杂度,适用于需要快速查找和有序存储的场景。
142 3
|
C++ 容器
【C++】map和set封装
【C++】map和set封装
108 2
|
存储 C++ 容器
【C++】map和set深度讲解(下)
【C++】map和set深度讲解(下)
145 2
|
存储 自然语言处理 Java
【C++】map和set深度讲解(上)
【C++】map和set深度讲解(上)
111 2
|
存储 算法 C++
C++一分钟之-扁平化映射与unordered_map
【7月更文挑战第5天】C++的STL `unordered_map`是键值对的快速查找容器,基于哈希表。常见问题包括哈希函数选择、键类型限制、内存管理和迭代顺序不确定性。要避免问题,需优化哈希函数,确保自定义类型支持哈希和比较操作,合理管理内存,不依赖迭代顺序。提供的代码示例展示了如何为自定义类型定义哈希函数并操作`unordered_map`。正确使用能提升代码效率。
231 0
C++一分钟之-扁平化映射与unordered_map