如何在不插入的情况下检查 std::map 是不是包含键?
Posted
技术标签:
【中文标题】如何在不插入的情况下检查 std::map 是不是包含键?【英文标题】:How to check if std::map contains a key without doing insert?如何在不插入的情况下检查 std::map 是否包含键? 【发布时间】:2011-04-22 15:27:12 【问题描述】:我发现检查重复项的唯一方法是插入并检查std::pair.second
的false
,但问题是如果密钥未使用,这仍然会插入一些东西,而我想要的是@987654324 @函数。
【问题讨论】:
How to find if a given key exists in a C++ std::map的可能重复 【参考方案1】:使用my_map.count( key )
;它只能返回 0 或 1,这本质上是您想要的布尔结果。
或者my_map.find( key ) != my_map.end()
也可以。
【讨论】:
@John:这有点过早优化的味道。在 GCC(我相信最合理的系统)上,map::count
被实现为find(__x) == end() ? 0 : 1;
。对于multimap
,您可能有性能争论,但这不是 OP 的问题,我仍然更喜欢优雅。
不,过早的优化参数只有在优化需要一些努力时才有效,在这种情况下它不会。
不正确。如果它使代码更易于阅读或消除不必要的开销,这还为时过早。在这种情况下,如果 count() 无论如何是通过 find() 实现的,那么直接调用 find() 就可以消除函数调用......所以,它是 mature 优化。我发现使用 find() 调用也更明显,但这纯粹是个人喜好。
在习惯使用库函数之前了解它们的性能并不是一个过早的优化。在这种情况下,你是对的,这并不重要,但 find 和 count 之间的微小风格差异也没有关系。我认为您将“过早的优化”言辞太过分了。您应该采取任何可以找到的“免费”优化习惯并将其用于日常开发。当编码人员屈服于在可读性/开发时间/等方面付出成本的陷阱时,所有这些都是为了无法衡量的“性能提升”,过早的优化言论成为正确的建议。
太远了,std 应该像地球上所有其他理智的地图类一样添加该死的has(k)
/ contains(k)
。界面设计差。 find() 方法过于冗长,count(k)
方法在语义上与has(k)
绝对不一样。就此而言,find(k)
也不是。查看此问题的观看次数。【参考方案2】:
Potatoswatter 的回答没问题,但我更喜欢用find
或lower_bound
代替。 lower_bound
特别有用,因为返回的迭代器随后可用于提示插入,如果您希望插入具有相同键的内容。
map<K, V>::iterator iter(my_map.lower_bound(key));
if (iter == my_map.end() || key < iter->first) // not found
// ...
my_map.insert(iter, make_pair(key, value)); // hinted insertion
else
// ... use iter->second here
【讨论】:
这与他所说的方式略有不同......唯一的区别是如果不需要插入,则可以跳过value
的计算。
当然,我知道 OP 不关心插入,所以基于 lower_bound
的解决方案是矫枉过正。我刚刚提到了我的回答“为了完整性”;就像我说的,你的完全足够了。 :-)
是的,这是一个很好的答案,我不反对任何事情。只是先验地指出与insert
替代方案的关系。实际上,如果使用multimap
,还有另一个区别,lower_bound
方法插入等效范围的开头,而普通的insert
方法添加到范围的末尾。
不是问题的答案,但我的糟糕问题让我在这里找到了正确的答案......我需要进行插入/更新。 :D
@Hunter 你能告诉我你的代码吗?如果它不是很大,我可能会为您审查它。【参考方案3】:
您的需求map.contains(key)
计划用于标准草案C++2a。 2017年由gcc 9.2实施。它也在当前的clang中。
【讨论】:
这是一个不错的功能!我认为它已经登陆 C++20。 cppreference.com以上是关于如何在不插入的情况下检查 std::map 是不是包含键?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不手动检查的情况下确定网站是不是使用 webassembly?