C++ std::map用法简介

本文详细介绍了C++标准模板库中的map容器的使用方法,包括初始化、插入、取值、查找及遍历等操作,并对比了不同取值方式的特点。
#include "map"   //引入头文件

初始化:

std::map <int, std::string> _map1;  //初始化
	//c++11中引入的,可以直接在初始化时赋值
	std::map <int, std::string> _map =   
	{
		{0,"11"},
		{2,"22"},
		{3,"33"},
	};

插入:

// 如果已经存在键值200,则会作赋值修改操作,如果没有则插入
	_map[200] = "booomm";
//通过insert插入
	_map.insert(std::pair<int, std::string>(4, "33333"));

取值:

用at和[]:

//Map中元素取值主要有at和[]两种操作,at会作下标检查,而[]不会。
	std::cout<< _map.at(100).c_str()<< std::endl;//使用at会进行关键字检查,因为没有100因此该语句会报错
	std::cout << _map.at(4).c_str() << std::endl;//因为已经有4了,不会报错
	
	std::cout << _map[300].c_str() << std::endl;//ID_Name中没有关键字200,使用[]取值会导致插入,因此不会报错,但打印结果为空

用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器:

auto iter=_map.find(200);
if(iter==_map.end()) 
{
   assert(false);  //若没有200这个元素,会返回end
   return;
}
auto value=iter->second;  //second返回iter的value


遍历:

for(auto item =_map.begin();item!=_map.end();item++)
{
     auto value= item->second;
     if(value==L"11")
     {
        //do someting.....
     }
}

参考资料:http://blog.csdn.net/shuzfan/article/details/53115922

<think>好的,我现在需要回答用户关于C++std::map的使用方法和示例的问题。首先,我得回忆一下std::map的基本概念和常用操作。std::mapC++标准模板库中的一个关联容器,以键值对的形式存储元素,并且按键的顺序自动排序。键是唯一的,每个键对应一个值。 用户可能希望了解如何声明和初始化map,插入元素,访问元素,遍历元素,查找元素以及删除元素等操作。根据提供的引用内容,引用[1]、[3]中有具体的代码示例,可以借鉴这些例子来说明不同的操作方法。同时,引用[2]提到了std::mapstd::unordered_map的区别,可能在回答时需要简要提及,以帮助用户选择合适的容器。 首先,我应该从基础开始,分步骤讲解各个操作。比如,声明一个map,插入元素的不同方法(使用insert函数或operator[]),访问元素的方式,如何检查元素是否存在,遍历map的方法,以及删除元素的几种方式。每个步骤都需要给出对应的代码示例,并解释代码的作用。同时,要注意提到std::map的有序性,因为这是它和unordered_map的主要区别之一。 另外,需要注意用户提到的“使用指南”和“示例”,所以回答需要结构清晰,每个部分都有明确的标题和代码示例。可能还需要提到性能方面的考虑,比如插入和查找的时间复杂度是O(log n),这对用户理解使用场景有帮助。 需要检查提供的引用内容中的代码是否正确,并确保示例代码符合C++标准。例如,引用[1]中使用了insert方法的不同形式,包括插入单个键值对、带位置提示的插入、以及范围插入。引用[3]则展示了使用operator[]插入元素,find方法检查存在性,以及基于范围的循环遍历。这些都可以作为示例的不同部分。 可能还需要补充一些其他常用操作,比如获取map的大小、判断是否为空、清空map等,但根据用户的问题,可能更关注基本使用方法和示例,所以这些可以简要提及或省略。 需要确保回答符合用户的中文要求,使用清晰的中文表达,避免术语错误。同时,注意格式要求:行内数学表达式用$...$,独立公式用$$...$$,但在这个问题中可能用不到数学公式,但需要检查是否有变量或代码需要正确排版。 最后,生成相关问题,这些问题应该与std::map的使用相关,可能包括性能优化、与其他容器的比较、常见错误等,参考之前提供的示例问题,但需要具体针对std::map。 现在整理一下回答的结构: 1. 基本概念:介绍std::map的特性,有序性,键唯一性。 2. 常用操作: a. 声明和初始化 b. 插入元素(insert和operator[]) c. 访问元素(operator[]和at) d. 查找元素(find、count) e. 遍历元素(迭代器、范围for循环) f. 删除元素(erase) 3. 示例代码:综合上述操作的完整示例 4. 性能与应用场景:时间复杂度,与unordered_map的比较 5. 注意事项:键的类型要求,插入重复键的处理 然后根据引用中的代码示例,整合到各个部分中,确保代码正确并附有解释。例如,引用[1]中的insert方法的不同用法,引用[3]中的operator[]插入和遍历。 需要确保回答中的代码部分使用正确的格式,用三个反引号包裹,并标明语言为cpp。同时,引用标识要正确添加,比如在提到插入已存在键时的处理,可以引用[1]中的示例。 最后生成相关问题,可能包括如何选择map和unordered_map,如何自定义比较函数,如何处理键冲突,性能优化技巧等。</think>以下是对C++中$std::map$的详细使用指南,结合代码示例和核心特性说明: --- ### 一、基本概念 $std::map$是C++标准库中的**有序关联容器**,存储键值对($key-value$),具有以下特性: - 按键自动升序排序(可自定义排序规则) - 键唯一,不允许重复 - 基于红黑树实现,插入/查找时间复杂度为$O(\log n)$[^2] --- ### 二、核心操作指南 #### 1. 声明与初始化 ```cpp #include <map> std::map<std::string, int> fruitCounts; // 键类型string,值类型int std::map<int, double> scores{{1, 90.5}, {2, 88.0}}; // 初始化列表 ``` #### 2. 插入元素 **方法一:$insert$函数** ```cpp // 插入单个键值对 fruitCounts.insert(std::pair<std::string, int>("apple", 5)); // 检查插入结果(处理重复键) auto [iter, success] = fruitCounts.insert({"apple", 10}); if (!success) { std::cout << "键已存在,当前值:" << iter->second << std::endl; // 输出已存在的值[^1] } // 范围插入(从另一个map复制部分元素) std::map<std::string, int> tempMap; tempMap.insert(fruitCounts.begin(), fruitCounts.find("cherry")); ``` **方法二:$operator[]$** ```cpp fruitCounts["banana"] = 3; // 直接赋值(若键不存在则自动创建) ``` #### 3. 访问元素 ```cpp // 通过键访问 int appleCount = fruitCounts["apple"]; // 不存在则创建默认值(危险!) int safeCount = fruitCounts.at("apple"); // 不存在则抛出异常 // 遍历访问 for (const auto& [fruit, count] : fruitCounts) { // C++17结构化绑定 std::cout << fruit << ": " << count << std::endl; } ``` #### 4. 查找与判断存在性 ```cpp auto it = fruitCounts.find("mango"); if (it != fruitCounts.end()) { std::cout << "找到芒果,数量:" << it->second << std::endl; } if (fruitCounts.count("orange") > 0) { // count返回0或1 std::cout << "橙子存在" << std::endl; } ``` #### 5. 删除元素 ```cpp fruitCounts.erase("apple"); // 通过键删除 fruitCounts.erase(it); // 通过迭代器删除 fruitCounts.erase(fruitCounts.begin(), fruitCounts.find("banana")); // 范围删除 ``` --- ### 三、完整示例 ```cpp #include <iostream> #include <map> int main() { std::map<std::string, int> inventory; // 插入元素 inventory.insert({"sword", 5}); inventory["shield"] = 3; inventory["potion"] = 10; // 修改值 inventory["potion"] += 2; // 安全查找 if (auto search = inventory.find("arrow"); search != inventory.end()) { std::cout << "箭矢数量:" << search->second << "\n"; } else { std::cout << "没有箭矢\n"; } // 遍历输出(按字母升序) for (const auto& [item, quantity] : inventory) { std::cout << item << "\t-> " << quantity << "\n"; } return 0; } ``` 输出: ``` 没有箭矢 potion -> 12 shield -> 3 sword -> 5 ``` --- ### 四、性能与选择建议 | 特性 | $std::map$ | $std::unordered\_map$ | |--------------------|---------------------|------------------------| | **排序** | 按键有序 | 无序 | | **实现结构** | 红黑树 | 哈希表 | | **时间复杂度** | $O(\log n)$ | 平均$O(1)$,最差$O(n)$[^2] | | **适用场景** | 需要有序遍历/范围查询 | 快速查找,不关心顺序 | --- ### 五、注意事项 1. 键类型必须支持$<$运算符(或提供自定义比较器) 2. $operator[]$访问不存在的键时会自动插入默认值 3. 迭代器失效:只有删除当前元素会使指向该元素的迭代器失效
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值