std::map 再学习

1. map中的元素其实就是一个pair.
2. map的键一般不能是指针, 比如int*, char*之类的, 会出错. 常用的就用string了,int也行.
3. map是个无序的容器, 而vector之类是有序的. 所谓有序无序是指放入的元素并不是按一定顺序放进去的, 而是乱序, 随机存放的(被映射后近似随机存放).所以遍历的时候有些效率差别.
4. 判断有没有找到该键的内容可以这样:
std::map<std::string,Record>::const_iterator cIter;
cIter = stdfile.m_map.find(s);
if (cIter == stdfile.m_map.end()) // 没找到就是指向END了   
{
m_vecMoreFile.push_back(s);
}
如果键的内容是指针的话, 应该用NULL指针也可以判断了.
5. 遍历:
std::map<std::string,Record>::iterator iter;
for (iter = m_map.begin(); iter != m_map.end(); iter++)
{
std::string s = iter->second.filename;
}
由于map内容可以相当一个PAIR, 那就简单了, 用iter->second就可以取得值了.

可顺便转个其它的几种用法:
1 头文件
#include <map>

2 定义
map<string, int> my_Map;
或者是typedef map<string, int> MY_MAP;
MY_MAP my_Map;

3 插入数据
(1) my_Map["a"] = 1;
(2) my_Map.insert(map<string, int>::value_type("b",2));
(3) my_Map.insert(pair<string,int>("c",3));
(4) my_Map.insert(make_pair("d",4));

4 查找数据和修改数据
(1) int i = my_Map["a"];
my_Map["a"] = i;
(2) MY_MAP::iterator my_Itr;
my_Itr.find("b");
int j = my_Itr->second;
my_Itr->second = j;
不过注意,键本身是不能被修改的,除非删除。

5 删除数据
(1) my_Map.erase(my_Itr);
(2) my_Map.erase("c");
还是注意,第一种情况在迭代期间是不能被删除的,道理和foreach时不能删除元素一样。

6 迭代数据
for (my_Itr=my_Map.begin(); my_Itr!=my_Map.end(); ++my_Itr) {}

7 其它方法
my_Map.size() 返回元素数目
my_Map.empty() 判断是否为空
my_Map.clear() 清空所有元素
可以直接进行赋值和比较:=, >, >=, <, <=, != 等等

遍历:

#include<iostream>
#include <map>
using namespace std;

int main(){
 map<int,int>M;
 M[1]=2;
 M[2]=3;
 map<int,int>::iterator iter;
 for (iter = M.begin(); iter != M.end(); iter++)
 {
  cout<<iter->first<<" "<<iter->second<<endl;
 }
 return 0;
}

 

总结:

       find();

       erase();

       std::map<std::string, int> map;

       map[std::string] = int;

       第一个参数

<think>好的,用户现在问的是“std::map是什么意思”。之前他们问了关于C++中哈希表如何获取索引的问题,我详细介绍了std::unordered_map和手动实现哈希表的方法。现在这个问题转向了std::map,需要明确两者的区别以及std::map的特性。 首先,用户可能对C++的关联容器不太熟悉,或者在学习过程中遇到了这两个容器,想了解它们的区别。我需要先解释std::map的基本概念,然后对比std::unordered_map,强调底层实现的不同,比如红黑树和哈希表。 接下来,用户可能想知道std::map的用途,比如什么时候使用它而不是哈希表。这时候需要提到有序性、查找效率、内存占用等方面的差异。例如,std::map的插入和删除操作是O(log n),而std::unordered_map平均是O(1),但最坏情况可能O(n)。同时,std::map保持元素有序,这在需要有序遍历时很有用。 还要注意用户可能的误区,比如认为std::map也是哈希表实现的。需要明确指出std::map是基于红黑树,属于有序关联容器,而std::unordered_map才是哈希表实现的无序容器。 另外,用户可能对如何选择两者感到困惑,所以需要给出使用场景的建议。比如需要有序数据时用std::map,需要快速访问且不关心顺序时用std::unordered_map。同时,可以提到自定义比较函数或哈希函数的情况,说明std::map的灵活性和适用场景。 最后,可能需要给出一些代码示例,比如声明、插入、遍历操作,以及如何自定义排序规则。这样用户能更直观地理解std::map的使用方法。同时,提醒用户注意性能差异,特别是在数据量大的情况下,选择合适的容器很重要。 总结下来,回答需要结构清晰,先定义std::map,对比其他容器,讲解底层实现,使用场景,代码示例,最后总结如何选择。确保用户能全面理解std::map的概念和应用。</think>在 C++ 中,`std::map` 是标准模板库(STL)提供的一个**有序关联容器**,用于存储键值对(Key-Value Pair),并根据键(Key)自动排序。其核心特性如下: --- ### **1. 基本定义** - **底层实现**:基于红黑树(Red-Black Tree,一种自平衡二叉搜索树)。 - **键的唯一性**:每个键唯一,不允许重复(若需允许重复键,可用 `std::multimap`)。 - **自动排序**:插入元素时,按键的**升序**自动排序(可通过自定义比较函数修改排序规则)。 - **时间复杂度**: - 插入、删除、查找操作:$O(\log n)$(因红黑树的高度平衡性)。 - 遍历操作:$O(n)$(按排序顺序遍历)。 --- ### **2. 与 `std::unordered_map` 的区别** | 特性 | `std::map` | `std::unordered_map` | |---------------------|--------------------------------|--------------------------------| | **底层结构** | 红黑树(有序) | 哈希表(无序) | | **插入/查找复杂度** | $O(\log n)$ | 平均 $O(1)$,最坏 $O(n)$ | | **内存占用** | 较高(树结构有额外指针开销) | 较低 | | **遍历顺序** | 按键升序遍历 | 无序,依赖哈希函数和桶分布 | | **适用场景** | 需要有序键或范围查询 | 只需快速访问,无需顺序 | --- ### **3. 核心用法示例** #### **(1) 声明与插入** ```cpp #include <map> #include <string> int main() { // 声明一个键为 string、值为 int 的 map std::map<std::string, int> fruit_prices; // 插入键值对(方式1:使用 insert) fruit_prices.insert(std::make_pair("apple", 10)); fruit_prices.insert({"banana", 20}); // 插入键值对(方式2:使用 operator[]) fruit_prices["orange"] = 15; // 若键不存在,会自动创建 return 0; } ``` #### **(2) 遍历与访问** ```cpp // 遍历输出(按键升序) for (const auto& pair : fruit_prices) { std::cout << pair.first << ": " << pair.second << std::endl; } // 输出顺序:apple → banana → orange(按字符串字典序) ``` #### **(3) 查找元素** ```cpp // 查找键 "apple" auto it = fruit_prices.find("apple"); if (it != fruit_prices.end()) { std::cout << "Price of apple: " << it->second << std::endl; } else { std::cout << "Apple not found!" << std::endl; } ``` #### **(4) 自定义排序规则** ```cpp // 按键的降序排列 struct CompareGreater { bool operator()(const std::string& a, const std::string& b) const { return a > b; // 降序 } }; std::map<std::string, int, CompareGreater> fruit_prices_desc; fruit_prices_desc["apple"] = 10; fruit_prices_desc["banana"] = 20; // 遍历顺序:orange → banana → apple(若存在) ``` --- ### **4. 适用场景** - **需要有序键**:例如按时间戳、字母顺序等遍历数据。 - **范围查询**:查找介于两个键之间的所有元素(如 `lower_bound` 和 `upper_bound` 方法)。 - **稳定性能**:红黑树保证最坏情况下仍为 $O(\log n)$,适合对延迟敏感的场景。 --- ### **5. 注意事项** - **键的类型要求**:必须支持 `<` 运算符或提供自定义比较函数。 - **内存效率**:相比 `std::unordered_map`,`std::map` 占用更多内存(因树节点存储左右子节点指针)。 - **修改键的值**:键本身是常量,不可修改;值可以自由修改。 --- ### **总结** `std::map` 是 C++ 中实现**有序键值对存储**的核心工具,适合需要按键顺序操作数据的场景。若无需排序且追求更高性能,可优先选择 `std::unordered_map`(基于哈希表)。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值