在面试流程(例如筛选)的早期阶段,一位 Google 招聘人员曾向我问过这个问题。
在C++中,当你使用std::map访问一个不存在的键时,行为取决于你是如何访问它的。
使用下标操作符 [] 访问时
如果键不存在,std::map 会默认插入一个该键的元素,并为其赋值为类型的默认值。比如,如果 map 的值类型是 int,那么它会插入该键并赋值为 0。
例子:
1 2 | std::map<int, int> myMap; int value = myMap[10]; // 如果键10不存在,会插入myMap[10] = 0 |
std::map<int, int> myMap; int value = myMap[10]; // 如果键10不存在,会插入myMap[10] = 0
使用 at() 方法访问时
如果键不存在,at() 会抛出 std::out_of_range 异常。
例子:
1 2 3 4 5 6 | std::map<int, int> myMap; try { int value = myMap.at(10); // 如果键10不存在,会抛出异常 } catch (const std::out_of_range& e) { std::cout << "Key not found!" << std::endl; } |
std::map<int, int> myMap; try { int value = myMap.at(10); // 如果键10不存在,会抛出异常 } catch (const std::out_of_range& e) { std::cout << "Key not found!" << std::endl; }
使用 find() 方法
find() 方法不会修改 map,它返回一个迭代器。如果键不存在,它会返回 map.end()。
例子:
1 2 3 4 5 6 7 | std::map<int, int> myMap; auto it = myMap.find(10); if (it == myMap.end()) { std::cout << "Key not found!" << std::endl; } else { std::cout << "Value: " << it->second << std::endl; } |
std::map<int, int> myMap; auto it = myMap.find(10); if (it == myMap.end()) { std::cout << "Key not found!" << std::endl; } else { std::cout << "Value: " << it->second << std::endl; }
C++ std::map 和 std::unordered_map的比较
std::unordered_map 处理不存在的键与 std::map 类似,但有一些差异,主要是因为它们内部的数据结构不同。
map 和 unordered_map 的区别:
- 顺序:std::map 是有序的(内部实现为平衡树),所以元素会按键的顺序排列。而 std::unordered_map 是无序的,使用哈希表存储元素,因此没有特定的顺序。
- 性能:std::unordered_map 通常有更快的平均访问时间(由于哈希结构,平均时间复杂度为 O(1)),而 std::map 的访问时间复杂度为 O(log n),因为其内部实现为树结构。然而,如果发生大量哈希冲突,unordered_map 在最坏情况下的时间复杂度可能是 O(n)。
总的来说,std::unordered_map 和 std::map 在处理不存在的键时,对于 []、at() 和 find() 的行为相似,但它们在顺序和性能方面存在差异。
总结
- 使用 [] 访问时,如果键不存在,map 会插入一个新元素并赋予默认值。
- 使用 at() 访问时,如果键不存在,会抛出异常。
- 使用 find() 可以检查键是否存在,而不会修改 map。
英文:C++: Access a Non-existent Key in std::map or std::unordered_map
强烈推荐
- 英国代购-畅购英伦
- TopCashBack 返现 (英国购物必备, 积少成多, 我2年来一共得了3000多英镑)
- Quidco 返现 (也是很不错的英国返现网站, 返现率高)
- 注册就送10美元, 免费使用2个月的 DigitalOcean 云主机(性价比超高, 每月只需5美元)
- 注册就送10美元, 免费使用4个月的 Vultr 云主机(性价比超高, 每月只需2.5美元)
- 注册就送10美元, 免费使用2个月的 阿里 云主机(性价比超高, 每月只需4.5美元)
- 注册就送20美元, 免费使用4个月的 Linode 云主机(性价比超高, 每月只需5美元) (折扣码: PodCastInit2022)
- PlusNet 英国光纤(超快, 超划算! 用户名 doctorlai)
- 刷了美国运通信用卡一年得到的积分 换了 485英镑
- 注册就送50英镑 – 英国最便宜最划算的电气提供商
- 能把比特币莱特币变现的银行卡! 不需要手续费就可以把虚拟货币法币兑换
微信公众号: 小赖子的英国生活和资讯 JustYYUK