如何查找给定的键是否存在于 std::map 中

问题描述 投票:0回答:15

我正在尝试检查给定的键是否在地图中,但有些做不到:

typedef map<string,string>::iterator mi;
map<string, string> m;
m.insert(make_pair("f","++--"));
pair<mi,mi> p = m.equal_range("f");//I'm not sure if equal_range does what I want
cout << p.first;//I'm getting error here

那么我怎样才能打印p中的内容呢?

c++ dictionary std stdmap
15个回答
969
投票

使用

map::find
map::end
:

if (m.find("f") == m.end()) {
  // not found
} else {
  // found
}

394
投票

要检查映射中是否存在特定键,请通过以下方式之一使用

count
成员函数:

m.count(key) > 0
m.count(key) == 1
m.count(key) != 0

map::find

文档
说:“另一个成员函数
map::count
可用于仅检查特定键是否存在。”

map::count

文档
说:“因为地图容器中的所有元素都是唯一的,所以该函数只能返回1(如果找到该元素)或零(否则)。”

要通过您知道存在的键从映射中检索值,请使用 map::at:

value = m.at(key)

map::operator[] 不同,如果指定的键不存在,

map::at
不会在映射中创建新键。


178
投票

C++20 为我们提供了

std::map::contains
来做到这一点。

#include <iostream>
#include <string>
#include <map>

int main()
{
    std::map<int, std::string> example = {{1, "One"}, {2, "Two"}, 
                                     {3, "Three"}, {42, "Don\'t Panic!!!"}};

    if(example.contains(42)) {
        std::cout << "Found\n";
    } else {
        std::cout << "Not found\n";
    }
}

57
投票

您可以使用

.find()

map<string,string>::iterator i = m.find("f");

if (i == m.end()) { /* Not found */ }
else { /* Found, i->first is f, i->second is ++-- */ }

48
投票

C++17 通过带有初始化器的 If 语句进一步简化了这一点。 这样你就可以鱼与熊掌兼得了。

if ( auto it{ m.find( "key" ) }; it != std::end( m ) ) { // Use `structured binding` to get the key // and value. const auto&[ key, value ] { *it }; // Grab either the key or value stored in the pair. // The key is stored in the 'first' variable and // the 'value' is stored in the second. const auto& mkey{ it->first }; const auto& mvalue{ it->second }; // That or just grab the entire pair pointed // to by the iterator. const auto& pair{ *it }; } else { // Key was not found.. }
    

20
投票
m.find == m.end() // not found

如果您想使用其他API,请找到

m.count(c)>0



if (m.count("f")>0) cout << " is an element of m.\n"; else cout << " is not an element of m.\n";
    

13
投票
我想你想要

map::find

。如果 
m.find("f")
 等于 
m.end()
,则未找到密钥。否则,find 返回一个指向找到的元素的迭代器。

错误是因为

p.first

是一个迭代器,它不适用于流插入。将最后一行更改为 
cout << (p.first)->first;
p
 是一对迭代器,
p.first
 是迭代器,
p.first->first
 是键字符串。

一张地图对于给定的键只能有一个元素,所以

equal_range

 不是很有用。它是为映射定义的,因为它是为所有关联容器定义的,但它对于多重映射更有趣。


9
投票
template <typename T, typename Key> bool key_exists(const T& container, const Key& key) { return (container.find(key) != std::end(container)); }

当然,如果你想变得更奇特,你可以随时模板化一个函数,该函数也采用已找到的函数和未找到的函数,如下所示:

template <typename T, typename Key, typename FoundFunction, typename NotFoundFunction> void find_and_execute(const T& container, const Key& key, FoundFunction found_function, NotFoundFunction not_found_function) { auto& it = container.find(key); if (it != std::end(container)) { found_function(key, it->second); } else { not_found_function(key); } }

并像这样使用它:

std::map<int, int> some_map; find_and_execute(some_map, 1, [](int key, int value){ std::cout << "key " << key << " found, value: " << value << std::endl; }, [](int key){ std::cout << "key " << key << " not found" << std::endl; });

这样做的缺点是想出一个好名字,“find_and_execute”很尴尬,我想不出更好的名字......


6
投票
map<string, string> m;

检查 key 是否存在,并返回出现次数(map 中为 0/1):

int num = m.count("f"); if (num>0) { //found } else { // not found }

检查key是否存在,并返回迭代器:

map<string,string>::iterator mi = m.find("f"); if(mi != m.end()) { //found //do something to mi. } else { // not found }


在你的问题中,由坏的

operator<<

过载引起的错误,因为
p.first
map<string, string>
,你无法打印出来。尝试这个:

if(p.first != p.second) { cout << p.first->first << " " << p.first->second << endl; }
    

2
投票
小心地将查找结果与地图“m”的结尾进行比较,因为所有答案都有 上面完成 地图::迭代器 i = m.find("f");

if (i == m.end()) { } else { }

您不应该尝试执行任何操作,例如如果迭代器 i 等于 m.end() 则打印键或值,否则会导致分段错误。


0
投票
比较 std::map::find 和 std::map::count 的代码,我认为第一个可能会产生一些性能优势:

const_iterator find(const key_type& _Keyval) const { // find an element in nonmutable sequence that matches _Keyval const_iterator _Where = lower_bound(_Keyval); // Here one looks only for lower bound return (_Where == end() || _DEBUG_LT_PRED(this->_Getcomp(), _Keyval, this->_Key(_Where._Mynode())) ? end() : _Where); } size_type count(const key_type& _Keyval) const { // count all elements that match _Keyval _Paircc _Ans = equal_range(_Keyval); // Here both lower and upper bounds are to be found, which is presumably slower. size_type _Num = 0; _Distance(_Ans.first, _Ans.second, _Num); return (_Num); }
    


-1
投票
我知道这个问题已经有一些很好的答案,但我认为我的解决方案值得分享。

它适用于

std::map

std::vector<std::pair<T, U>>
,并且可从 C++11 开始使用。

template <typename ForwardIterator, typename Key> bool contains_key(ForwardIterator first, ForwardIterator last, Key const key) { using ValueType = typename std::iterator_traits<ForwardIterator>::value_type; auto search_result = std::find_if( first, last, [&key](ValueType const& item) { return item.first == key; } ); if (search_result == last) { return false; } else { return true; } }
    

-7
投票
map <int , char>::iterator itr; for(itr = MyMap.begin() ; itr!= MyMap.end() ; itr++) { if (itr->second == 'c') { cout<<itr->first<<endl; } }
    

-8
投票
如果你想比较成对的地图,你可以使用这个方法:

typedef map<double, double> TestMap; TestMap testMap; pair<map<double,double>::iterator,bool> controlMapValues; controlMapValues= testMap.insert(std::pair<double,double>(x,y)); if (controlMapValues.second == false ) { TestMap::iterator it; it = testMap.find(x); if (it->second == y) { cout<<"Given value is already exist in Map"<<endl; } }

这是一项有用的技术。

© www.soinside.com 2019 - 2024. All rights reserved.