如何查找C ++ std :: map中是否存在给定键

时间:2009-12-21 12:55:03

标签: c++ dictionary stl

我正在尝试检查给定的密钥是否在地图中,但有些不能这样做:

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中的内容?

14 个答案:

答案 0 :(得分:600)

使用map::find

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

答案 1 :(得分:280)

要检查地图中是否存在特定密钥,请使用以下某种方式使用count成员函数:

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

map::find的{​​{3}}说:“另一个成员函数map::count可用于检查特定密钥是否存在。”

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

要通过您知道存在的密钥从地图中检索值,请使用documentation

value = m.at(key)

documentation不同,如果指定的密钥不存在,map::at将不会在地图中创建新密钥。

答案 2 :(得分:33)

您可以使用.find()

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

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

答案 3 :(得分:13)

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";

答案 4 :(得分:12)

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

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

地图只能有一个给定键的元素,因此equal_range不是很有用。它是为map定义的,因为它是为所有关联容器定义的,但对于multimap来说它更有趣。

答案 5 :(得分:7)

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";
    }
}

答案 6 :(得分:4)

map<string, string> m;

检查密钥是否存在,并返回发生的次数(地图中为0/1):

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

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

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

在您的问题中,错误operator<<导致错误导致错误,因为p.firstmap<string, string>,您无法将其打印出来。试试这个:

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

答案 7 :(得分:4)

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”很尴尬,我无法想出更好的东西......

答案 8 :(得分:3)

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

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

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

答案 9 :(得分:2)

C++17通过If statement with initializer进行了简化。 这样,您就可以吃蛋糕了。

if ( auto it{ m.find( "key" ) }; it != std::end( m ) ) 
{
    // Destructure the returned pair in to 
    // its sub components. Get them by reference.
    // You can also get them by value.
    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.
    auto& mkey{ it->first };
    auto& mvalue{ it->second };

    // That or just grab the entire pair pointed
    // to by the iterator.
    auto& pair{ *it };
} 
else 
{
   // Key was not found..
}

答案 10 :(得分: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);
    }

答案 11 :(得分:0)

我知道这个问题已经有了很好的答案,但是我认为我的解决方案值得分享。

它同时适用于std::mapstd::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;
    }
}

答案 12 :(得分:-3)

如果你想比较一对地图你可以使用这个方法:

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;
    }
}

这是一种有用的技术。

答案 13 :(得分:-3)

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