【工作中学习2】Map的使用及排序(第三个参数)

本文详细介绍了Map数据结构的原理与应用,包括其特点、内部数据结构、使用方法及示例代码,并通过程序举例展示了如何在C++中利用Map进行数据存储与检索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  项目进行中,使用到Map(std::map),Map要点整理如下:

  1. Map,也叫关联数组,提供key/value(键/值对),key用来索引,value是被存储和检索的数据。

  2. key值唯一(Multimap除外)。

  3. Map的内部数据结构是红黑树

  3. 可以用下标操作符,添加Map中的数据,例如map[1] = 2;,用下标操作符查找数据时,如果数据不存在,会被自动插入到Map中。

  4. Map中的数据默认按照由key从小到大排序(less),可以修改第三个参数(可选)来修改排序法则。

 

  程序举例:

 1 // testMap.cpp : Defines the entry point for the console application.
 2 //
 3 
 4 #include "stdafx.h"
 5 #include <string>
 6 #include <map>
 7 #include <iostream>
 8 
 9 struct SortMap  
10 {
11     bool operator ()( const int i1, const int i2 )  
12     {  
13         return i1 > i2;  
14     }  
15 };
16 
17 //traverse the map
18 void traverseMap(const std::map<int, std::string>& map)
19 {
20     std::map<int, std::string>::const_iterator iter = map.begin();
21     
22     while(iter != map.end())
23     {
24         std::cout << "" << iter->first << "," << iter->second << std::endl;
25         iter++;
26      }
27 }
28 
29 void traverseSortMap(const std::map<int, std::string, SortMap>& map)
30 {
31     std::map<int, std::string, SortMap>::const_iterator iter = map.begin();
32 
33     while(iter != map.end())
34     {
35         std::cout << "" << iter->first << "," << iter->second << std::endl;
36         iter++;
37     }
38 }
39 
40 
41 int _tmain(int argc, _TCHAR* argv[])
42 {
43     std::map<int, std::string> map1;
44     map1[1] = "no";
45     map1[6] = "hi";
46     map1[5] = "me";
47     map1[9] = "ok";
48     
49     traverseMap(map1);
50     std::cout << "-------------------------------------------" << std::endl;
51     
52     std::map<int, std::string, SortMap> map2;
53     map2[1] = "no";
54     map2[6] = "hi";
55     map2[5] = "me";
56     map2[9] = "ok";
57     
58     traverseSortMap(map2);
59     
60     system("pause");
61     return 0;
62 }

  

  运行结果:

  

 

  继续努力~

转载于:https://www.cnblogs.com/KevinSong/p/3725133.html

<think>首先,用户的问题是:“我想查询C++中map容器第三个参数的作用及用法 请问C++ map constructor third parameter comparator explanation”。翻译成英文是:“I want to inquire about the role and usage of the third parameter of the map container in C++. Please explain the comparator in the C++ map constructor.” 关键点: - C++ 中的 `std::map` 容器。 - 构造函数的第三个参数:比较器(comparator)。 在 C++ 中,`std::map` 是一个关联容器,存储键值对,按键排序。标准形式是: ```cpp template < class Key, class T, class Compare = std::less<Key>, class Allocator = std::allocator<std::pair<const Key, T>> > class map; ``` - 第三个模板参数是 `Compare`,默认是 `std::less<Key>`。 - 在构造函数中,你可以传递一个比较器对象作为第三个参数。 比较器的作用: - 它定义了键的排序顺序。 - 默认是升序(使用 `std::less<Key>`),但你可以自定义比较函数或函数对象来改变顺序,例如降序或基于自定义逻辑。 用法: - 比较器必须是一个可调用对象,接受两个键类型的参数,并返回一个布尔值,表示第一个参数是否应该在第二个参数之前。 - 它可以是函数指针、函数对象(functor)或 lambda 表达式。 示例: 1. 使用默认比较器(升序): ```cpp std::map<int, std::string> myMap; // 默认使用 std::less<int> ``` 2. 使用自定义比较器实现降序: ```cpp struct CompareDesc { bool operator()(int a, int b) const { return a > b; // 降序 } }; std::map<int, std::string, CompareDesc> myMap; ``` 3. 使用 lambda 表达式(在 C++11 及以后): ```cpp auto comp = [](int a, int b) { return a > b; }; std::map<int, std::string, decltype(comp)> myMap(comp); ``` 在构造函数中,第三个参数是用于比较器的实例。例如: ```cpp std::map<Key, Value, Compare> myMap(Compare()); ``` 但通常,我们直接在模板参数中指定比较器类型,并在需要时传递比较器对象。 现在,根据系统级指令: - 所有行内数学表达式用 `$...$`,但这里没有数学,所以可能不需要。 - 独立公式用 `$$...$$`,但这里主要是代码。 - LaTeX 语法正确:在代码块中,使用 Markdown 代码块。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾添加引用标识:但用户没有提供引用,所以可能不需要添加。参考站内引用说“上述引用仅供参考”,但这里没有引用。我应该确保回答真实可靠。 回答结构: - 清晰解释第三个参数的作用。 - 提供用法示例。 - 用中文。 - 最后生成相关问题。 生成相关问题: - 基于主题,如比较器的其他用法、性能影响、常见错误等。 最终回答结构: 1. 解释第三个参数的作用。 2. 描述用法和示例。 3. 代码示例。 4. 相关问题。</think>### C++ map 容器第三个参数(比较器)的作用及用法 在 C++ 中,`std::map` 是一个关联容器,用于存储键值对(key-value pairs)。其构造函数支持多个参数,其中**第三个参数是用于定义键(key)排序规则的比较器(comparator)**。默认情况下,`std::map` 使用 `std::less<Key>` 实现升序排序,但通过自定义比较器,您可以控制键的排序逻辑(如降序或自定义规则)。 #### 作用 1. **定义排序顺序**:比较器决定了键在容器中的排列方式(如升序、降序或基于自定义逻辑)。 2. **确保唯一性**:`std::map` 要求键唯一,比较器用于判断键是否相等(如果 `comp(a, b) == false` 且 `comp(b, a) == false`,则视为 `a == b`)。 3. **支持自定义类型**:当键是自定义类或结构体时,比较器可指定排序依据(如按成员变量排序)。 #### 用法 比较器必须是一个**可调用对象**(callable object),接受两个键类型的参数,并返回 `bool` 值: - 如果返回 `true`,表示第一个参数应排在第二个参数之前。 - 如果返回 `false`,表示第一个参数不应排在第二个参数之前(可能相等或靠后)。 比较器可以是: - **函数对象(Functor)**:定义一个重载 `operator()` 的类。 - **函数指针**:指向普通函数的指针。 - **Lambda 表达式**(C++11 及以上)。 ##### 基本语法 ```cpp std::map<KeyType, ValueType, ComparatorType> mapName(ComparatorInstance); ``` - `ComparatorType`:比较器的类型(如函数对象类名)。 - `ComparatorInstance`:比较器的实例(可省略,如果比较器有默认构造函数)。 #### 示例代码 以下示例演示如何自定义比较器实现降序排序和自定义排序: ```cpp #include <iostream> #include <map> #include <string> // 示例 1:使用函数对象实现降序排序 struct DescendingComparator { bool operator()(int a, int b) const { return a > b; // 降序:a > b 时返回 true,表示 a 应排在 b 前 } }; // 示例 2:函数指针实现自定义排序(按字符串长度排序) bool LengthComparator(const std::string& a, const std::string& b) { return a.length() < b.length(); // 按字符串长度升序 } int main() { // 示例 1:降序排序使用函数对象) std::map<int, std::string, DescendingComparator> map1; map1.insert({3, "Apple"}); map1.insert({1, "Banana"}); map1.insert({2, "Cherry"}); // 输出:3:Apple, 2:Cherry, 1:Banana(降序) // 示例 2:按字符串长度排序使用函数指针) std::map<std::string, int, decltype(&LengthComparator)> map2(LengthComparator); map2.insert({"Apple", 5}); map2.insert({"Fig", 3}); map2.insert({"Banana", 6}); // 输出:Fig:3, Apple:5, Banana:6(长度升序:3<5<6) // 示例 3:Lambda 表达式实现自定义排序(C++11 及以上) auto lambdaComp = [](int a, int b) { return a % 3 < b % 3; }; // 按模 3 的值排序 std::map<int, std::string, decltype(lambdaComp)> map3(lambdaComp); map3.insert({5, "Five"}); map3.insert({2, "Two"}); map3.insert({8, "Eight"}); // 输出:2:Two(模 3=2), 5:Five(模 3=2), 8:Eight(模 3=2)— 注意:键需唯一,此处仅为演示逻辑 } ``` #### 注意事项 1. **性能影响**:比较器的复杂度影响 `std::map` 的操作效率(如插入、查找为 $O(\log n)$)。 2. **严格弱序**:比较器必须满足[严格弱序(Strict Weak Ordering)](https://en.cppreference.com/w/cpp/named_req/Compare)[^1]: - 不可反身:`comp(a, a) == false`。 - 可传递:若 `comp(a, b) == true` 且 `comp(b, c) == true`,则 `comp(a, c) == true`。 - 反对称:若 `comp(a, b) == true`,则 `comp(b, a) == false`。 3. **默认行为**:如果省略第三个参数,`std::map` 使用 `std::less<Key>`(升序)。 通过自定义比较器,您可以灵活控制 `std::map` 的行为,适应各种排序需求[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值