遍历 unordered_map
在C++中遍历unordered_map
可以通过多种方式实现,下面详细介绍常用的遍历方法及其特点:
一、使用迭代器遍历(最常用)
unordered_map
的迭代器是双向迭代器,可以通过begin()
和end()
获取迭代器范围。
1. C++11前的传统写法
#include <unordered_map>
#include <string>
#include <iostream>int main() {std::unordered_map<int, std::string> umap = {{1, "one"}, {2, "two"}, {3, "three"}};// 声明迭代器类型为unordered_map的迭代器std::unordered_map<int, std::string>::iterator it;for (it = umap.begin(); it != umap.end(); ++it) {std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;}return 0;
}
2. C++11及以后的auto简化写法
#include <unordered_map>
#include <string>
#include <iostream>int main() {std::unordered_map<int, std::string> umap = {{1, "one"}, {2, "two"}, {3, "three"}};// 使用auto自动推导迭代器类型for (auto it = umap.begin(); it != umap.end(); ++it) {std::cout << "Key: " << it->first << ", Value: " << it->second << std::endl;}return 0;
}
3. 基于范围的for循环(C++11)
#include <unordered_map>
#include <string>
#include <iostream>int main() {std::unordered_map<int, std::string> umap = {{1, "one"}, {2, "two"}, {3, "three"}};// 直接遍历元素,item是pair的引用for (auto& item : umap) {std::cout << "Key: " << item.first << ", Value: " << item.second << std::endl;}// 若不需要修改,建议用const引用for (const auto& item : umap) {std::cout << "Key: " << item.first << ", Value: " << item.second << std::endl;}return 0;
}
二、遍历键或值
1. 仅遍历键
#include <unordered_map>
#include <iostream>int main() {std::unordered_map<int, std::string> umap = {{1, "one"}, {2, "two"}, {3, "three"}};for (const auto& key : umap) {std::cout << "Key: " << key.first << std::endl;}return 0;
}
2. 仅遍历值
#include <unordered_map>
#include <iostream>int main() {std::unordered_map<int, std::string> umap = {{1, "one"}, {2, "two"}, {3, "three"}};for (const auto& value : umap) {std::cout << "Value: " << value.second << std::endl;}return 0;
}
三、使用迭代器遍历的注意事项
- 无序性:
unordered_map
基于哈希表实现,遍历时元素顺序是无序的,与插入顺序无关。 - 迭代器失效:
- 添加或删除元素可能导致迭代器失效(除了删除当前迭代器指向的元素)。
- 删除元素时,建议使用安全的迭代器操作:
for (auto it = umap.begin(); it != umap.end();) {if (it->first == 2) {it = umap.erase(it); // erase返回下一个迭代器} else {++it;} }
- const迭代器:若不需要修改元素,使用
const_iterator
:std::unordered_map<int, std::string>::const_iterator cit; for (cit = umap.begin(); cit != umap.end(); ++cit) {// 仅可读,不可修改 }
四、遍历性能考虑
- 时间复杂度:遍历
unordered_map
的时间复杂度为 (O(n)),其中 (n) 是元素数量。 - 空间复杂度:仅使用迭代器,为 (O(1))。
- 与有序容器的区别:
map
基于红黑树,遍历时按键的顺序排列;unordered_map
遍历时顺序随机。
五、示例:统计字符串中字符出现次数
#include <unordered_map>
#include <string>
#include <iostream>int main() {std::string str = "hello world";std::unordered_map<char, int> count;// 统计字符频率for (char c : str) {count[c]++;}// 遍历输出结果std::cout << "字符频率统计:" << std::endl;for (const auto& pair : count) {std::cout << "字符 '" << pair.first << "': " << pair.second << " 次" << std::endl;}return 0;
}
总结
遍历unordered_map
的核心是使用迭代器或基于范围的for循环,推荐使用C++11的auto
和引用语法来简化代码。需要注意其无序性和迭代器失效问题,根据场景选择合适的遍历方式。