C++ multimap如何正确查找指定键对应的所有键值对
原代码问题
你写的实现无法得到正确结果。multimap属于有序关联容器,相同键的元素在内存中是连续存放的,但你的循环终止条件设为itr != mp.end(),会从第一个键为1的元素开始,一直遍历到整个容器的最后一个元素——示例里键为11、12的条目也会被打印出来,不符合查找特定键对应所有值的需求。
合规实现方法
下面是三种常用的正确写法,按需选用即可:
- 方法1:
equal_range(最推荐,兼容性好、效率最高)equal_range会直接返回目标键对应的起止迭代器:第一个迭代器指向该键的第一个匹配元素,第二个迭代器指向该键最后一个匹配元素的下一个位置,遍历这个闭开区间就能拿到所有对应条目,不会越界访问其他键的元素。
示例代码:
#include <iostream> #include <map> using namespace std; int main() { multimap<int, int> mp; mp.insert({1, 2}); mp.insert({11, 22}); mp.insert({12, 42}); mp.insert({1, 2}); mp.insert({1, 2}); auto res = mp.equal_range(1); for (auto it = res.first; it != res.second; ++it) { cout << it->first << '\t' << it->second << '\n'; } return 0; }
- 方法2:
lower_bound+upper_bound组合
逻辑和equal_range完全等价:lower_bound(1)拿到第一个键不小于1的位置,upper_bound(1)拿到第一个键大于1的位置,两个迭代器中间的区间就是所有键为1的元素。
示例代码:
#include <iostream> #include <map> using namespace std; int main() { multimap<int, int> mp; mp.insert({1, 2}); mp.insert({11, 22}); mp.insert({12, 42}); mp.insert({1, 2}); mp.insert({1, 2}); auto start = mp.lower_bound(1); auto end = mp.upper_bound(1); for (auto it = start; it != end; ++it) { cout << it->first << '\t' << it->second << '\n'; } return 0; }
- 方法3:C17及以上版本范围过滤写法
如果你的编译环境支持C17及更新的标准,可以用范围视图直接过滤目标键,代码可读性更高:
#include <iostream> #include <map> #include <ranges> using namespace std; int main() { multimap<int, int> mp; mp.insert({1, 2}); mp.insert({11, 22}); mp.insert({12, 42}); mp.insert({1, 2}); mp.insert({1, 2}); for (const auto& [k, v] : mp | views::filter([](const auto& p) { return p.first == 1; })) { cout << k << '\t' << v << '\n'; } return 0; }
补充说明:前两种方法的时间复杂度是O(log n),和find操作效率一致,是最优解;第三种范围过滤的写法是线性遍历整个容器,效率更低,仅适合代码量小、对性能不敏感的场景使用。
内容的提问来源于stack exchange,提问作者zodiac
相关产品推荐
相关产品推荐

