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

发布于 2024-08-15 08:03:57 字数 326 浏览 6 评论 0 原文

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

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

I'm trying to check if a given key is in a map and somewhat can't do it:

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

so how can I print what is in p?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

假装爱人 2024-08-22 08:03:58

使用 map::findmap::end

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

Use map::find and map::end:

if (m.find("f") == m.end()) {
  // not found
} else {
  // found
}
爱她像谁 2024-08-22 08:03:58

要检查映射中是否存在特定键,请按以下方式之一使用 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 不会在映射中创建新的键。

To check if a particular key in the map exists, use the count member function in one of the following ways:

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

The documentation for map::find says: "Another member function, map::count, can be used to just check whether a particular key exists."

The documentation for map::count says: "Because all elements in a map container are unique, the function can only return 1 (if the element is found) or zero (otherwise)."

To retrieve a value from the map via a key that you know to exist, use map::at:

value = m.at(key)

Unlike map::operator[], map::at will not create a new key in the map if the specified key does not exist.

海未深 2024-08-22 08:03:58

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

C++20 gives us std::map::contains to do that.

#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";
    }
}
杀お生予夺 2024-08-22 08:03:58

您可以使用.find()

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

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

You can use .find():

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

if (i == m.end()) { /* Not found */ }
else { /* Found, i->first is f, i->second is ++-- */ }
写给空气的情书 2024-08-22 08:03:58

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

C++17 simplified this a bit more with an If statements with initializer.
This way you can have your cake and eat it too.

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..
}
情仇皆在手 2024-08-22 08:03:58
m.find == m.end() // not found 

如果你想使用其他API,那么找到go for 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";
m.find == m.end() // not found 

If you want to use other API, then find go for 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";
笑,眼淚并存 2024-08-22 08:03:58

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

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

一张地图对于给定的键只能有一个元素,因此 equal_range 并不是很有用。它是为映射定义的,因为它是为所有关联容器定义的,但它对于多重映射更有趣。

I think you want map::find. If m.find("f") is equal to m.end(), then the key was not found. Otherwise, find returns an iterator pointing at the element found.

The error is because p.first is an iterator, which doesn't work for stream insertion. Change your last line to cout << (p.first)->first;. p is a pair of iterators, p.first is an iterator, p.first->first is the key string.

A map can only ever have one element for a given key, so equal_range isn't very useful. It's defined for map, because it's defined for all associative containers, but it's a lot more interesting for multimap.

凌乱心跳 2024-08-22 08:03:58
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”很尴尬,我想不出更好的办法......

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

Of course if you wanted to get fancier you could always template out a function that also took a found function and a not found function, something like this:

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

And use it like this:

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

The downside to this is coming up with a good name, "find_and_execute" is awkward and I can't come up with anything better off the top of my head...

百善笑为先 2024-08-22 08:03:58
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.firstmap,你可以不打印出来。试试这个:

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

check key exist or not, and return number of occurs(0/1 in map):

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

check key exist or not, and return iterator:

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

in your question, the error caused by bad operator<< overload, because p.first is map<string, string>, you can not print it out. try this:

if(p.first != p.second) {
    cout << p.first->first << " " << p.first->second << endl;
}
南城旧梦 2024-08-22 08:03:58

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

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

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

Be careful in comparing the find result with the the end like for map 'm' as all answer have
done above
map::iterator i = m.find("f");

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

you should not try and perform any operation such as printing the key or value with iterator i if its equal to m.end() else it will lead to segmentation fault.

国产ˉ祖宗 2024-08-22 08:03:58

比较 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);
    }

Comparing the code of std::map::find and std::map::count, I'd say the first may yield some performance advantage:

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);
    }
╰◇生如夏花灿烂 2024-08-22 08:03:58

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

它适用于 std::mapstd::vector> 并且可从 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;
    }
}

I know this question already has some good answers but I think my solution is worth of sharing.

It works for both std::map and std::vector<std::pair<T, U>> and is available from 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;
    }
}
浮世清欢 2024-08-22 08:03:58

find()contains() 可以使用。根据文档。两种方法平均花费恒定时间,在最坏情况下花费线性时间。

Both find() and contains() can be used. According to the documentation. Both methods take constant time on average and linear time in the worst case.

像你 2024-08-22 08:03:58
map <int , char>::iterator itr;
    for(itr = MyMap.begin() ; itr!= MyMap.end() ; itr++)
    {
        if (itr->second == 'c')
        {
            cout<<itr->first<<endl;
        }
    }
map <int , char>::iterator itr;
    for(itr = MyMap.begin() ; itr!= MyMap.end() ; itr++)
    {
        if (itr->second == 'c')
        {
            cout<<itr->first<<endl;
        }
    }
故笙诉离歌 2024-08-22 08:03:58

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

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

这是一个有用的技术。

If you want to compare pair of map you can use this method:

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

This is a useful technique.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文