map和multimap类是一种键—值对容器,可以根据键查找到对应的值,与我们平时学的字典很相似。
map和multimap类也是STL封装的一种模板类,区别在于:map类只能存储唯一的键,而multimap能够存储重复的键。
为实现快速查找,map和multimap的内部结构类似于二叉树。 也就是说在map和multimap中插入元素时将进行排序。同样映射类不能像vector那样可以使用其他元素替换给定位置的元素,位于map中特定位置的元素不能替换为值不同的新元素,这是因为map将把新元素同二叉树中的其他元素进行比较,进而将它放在其他的位置。
如果们需要使用map或multimap类时,需要定义头文件:
#include ;
我们需要了解一下map实例化语法:
map <keyType, valueType, Predicate=std::less <keyType> > mapObject;
multimap <keyType, valueType, Predicate=std::greater <keyType> >mmapObject;
这些语法参数如下:
keyType:代表的是键的类型;
valueType:代表的是值的类型;
less/greater: 用作排序标准。less是升序排序, greater是降序排序。
常见的实例化方法如下:
#include
#include
#include
#include
using namespace std;
//实例化
int main() {
//1、实例化1
map <int, string> map1;
multimap <int, string> mmap1;
//2、实例化2
map<int, string> map2(map1);
multimap<int, string> mmap2(mmap1);
//3、实例化3
map<int, string> map3(map1.begin(), map1.end());
multimap<int, string> mmap3(mmap1.begin(), mmap1.end());
return 0;
}
在实例化语法中第三个参数less/greater是定义元素排序的顺序。如果在实例化中,没有指定哪种排序方式,默认升序排序。若想指定排序方式,有两种方式:
(1) 利用语法中提供的两种方式less/greater:
//1、升序实例化
map<int, string, less<int>> map1;
//1、降序实例化
multimap<int, string, less<int>> mmap1;
(1) 自定义排序标准:
//自定义键的名称
template <typename KeyType1>
//自定义1
struct GreaterSort
{
bool operator()(const KeyType1& key1, const KeyType1& key2) {
return (key1 > key2);
}
};
//自定义2
template <typename KeyType2>
struct LessSort
{
bool operator()(const KeyType2& key3, const KeyType2& key4) {
return (key3 < key4);
}
};
int main() {
//1、升序实例化
map<int, string, less<int>> map1;
multimap<int, string, less<int>> mmap1;
//2、降序实例化
map<int, string, greater<int>> map2;
multimap<int, string, greater<int>> mmap2;
//1、自定义升序序实例化
map<int, string, LessSort<int>> map3(map1.cbegin(), map1.cend());
multimap<int, string, LessSort<int>> mmap3(mmap1.cbegin(), mmap1.cend());
//2、自定义降序实例化
map<int, string, GreaterSort<int>> map4(map2.cbegin(), map2.cend());
multimap<int, string, GreaterSort<int>> mmap4(mmap2.cbegin(), mmap2.cend());
return 0;
}
map和multimap类也有对应的成员函数,insert()函数就是向mao中插入新的键值对,常见的方法有四种:
#include
#include
#include
#include
using namespace std;
template <typename T>
// 显示内容函数
void DisplayContents(const T& Input)
{
for (auto iElement = Input.cbegin(); iElement != Input.cend(); ++iElement)
cout << iElement->first << " " << iElement->second << endl;
cout << endl;
}
//1、insert()插入函数
int main() {
map<int, string, less<int>>map1;
// 插入方法1
map1.insert(map<int, string>::value_type(3, "Three"));
// 插入方法2
map1.insert(make_pair(1, "One"));
// 插入方法3
map1.insert(pair<int, string>(10, "Ten"));
// 插入方法4,采用类似于数组的语法进行插入。
map1[8] = "Eight";
cout << "键:值" << endl;
DisplayContents(map1);
return 0;
}
经过四种不同方式的插入后,map有四个键值对:
map和multimap提供了成员函数find(),能够根据给定的键找到对应的值。find()函数返回的是一个迭代器:
map1 <int, string>::const_iterator iFound = map1.find(Key);
使用find()查找元素时,需要检查迭代器,确保find()成功,再使用该函数访问找到的值。
//2、find()查找函数--map
int main() {
map<int, string, less<int>> map1;
map1.insert(make_pair(1, "One"));
map1.insert(pair<int, string>(2, "Two"));
map1.insert(map<int, string>::value_type(3, "Three"));
map1[4] = "Four";
cout << "键:值" << endl;
DisplayContents(map1);
//根据输入键,查找是否存在map中
int num;
cout << "please input one key:" << endl;
cin >> num;
//根据键寻找对应值
auto isFound = map1.find(num);
if (isFound != map1.end())
{
cout << "Key:" << isFound->first << " 's value is: " << isFound->second << endl;
}
else
{
cout << "Key:" << num << " is not in map1! " << endl;
}
cout << endl;
return 0;
}
如果使用的是multimap,容器可能包含多个键相同的键值对,因此需要找到与指定键对应的所有值。所以,可先使用count()
确定有多少个值与指定的键对应,再对迭代器递增,以访问所有对应的值。
//2、find()查找函数--multimap
int main() {
multimap <int, string, less<int>> map2;
map2.insert(make_pair(8, "One"));
map2.insert(pair<int, string>(2, "Two"));
map2.insert(map<int, string>::value_type(3, "Three"));
map2.insert(map<int, string>::value_type(2, "2222"));
cout << "键:值" << endl;
DisplayContents(map2);
//根据输入键,查找是否存在map中
int num;
cout << "please input one key:" << endl;
cin >> num;
auto isFound = map2.find(num);
if (isFound != map2.end())
{
size_t nums = map2.count(num);
for (size_t ncounter = 0; ncounter < nums; ++ncounter)
{
cout << "Key:" << isFound->first << " 's value "<<"Val["<<ncounter<<"]"<<"is: " << isFound->second << endl;
++isFound;
}
}
else
cout << "Key:" << num << " is not in map1! " << endl;
return 0;
}
map和multimap提供了成员函数erase(),能够删除容器中的元素,删除的方式有多种:
//3、删除函数erase()
int mainerase()
{
multimap<int, string, less<int>>map1;
// 插入元素
map1.insert(make_pair(8, "Eight"));
map1.insert(make_pair(1, "One"));
map1.insert(make_pair(6, "Six"));
map1.insert(make_pair(10, "Ten"));
map1.insert(make_pair(15, "Fifteen"));
// 显示键值
cout << "键 :值" << endl;
DisplayContents(map1);
// 1、删除键1对应的键值对
map1.erase(1);
cout << "删除键1对应的键值对后:" << endl;
DisplayContents(map1);
// 2、删除迭代器指向的元素
auto iFound = map1.find(8);
map1.erase(iFound);
cout << "删除键8对应的键值对后:" << endl;
DisplayContents(map1);
// 3、删除指定范围内(6至10)的元素
map1.erase(map1.lower_bound(6), map1.lower_bound(15));
cout << "删除指定范围内(从6开始,到15之前)的元素:" << endl;
DisplayContents(map1);
return 0;
}
最后,长话短说,大家看完就好好动手实践一下,切记不能三分钟热度、三天打鱼,两天晒网。大家也可以自己尝试写写博客,来记录大家平时学习的进度,可以和网上众多学者一起交流、探讨,我也会及时更新,来督促自己学习进度。一开始提及的博主【AI菌】,个人已关注,并订阅了相关专栏(对我有帮助的),希望大家觉得不错的可以点赞、关注、收藏。