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

The*_* do 412 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
Run Code Online (Sandbox Code Playgroud)

那么如何打印p中的内容呢?

小智 648

使用 map::find

if ( m.find("f") == m.end() ) {
  // not found
} else {
  // found
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你只想检查是否存在某个键,你可能宁愿使用[`map :: count`](http://www.cplusplus.com/reference/map/map/count/) (94认同)
  • @goelakash几乎没有; 它只是`count`返回一个`int`而```返回一个整个迭代器.你保存了迭代器的构造:)显然,如果你之后要使用*值,如果它存在,请使用find并存储其结果. (30认同)
  • @tomsmeding std :: map中只有一个键.因此,计数将为0或1.一个比另一个更有效吗? (8认同)
  • @tomsmeding如果您正在使用多图,则必须查看整个容器.在这种情况下,find()可能会更快. (8认同)
  • **对于那些追求速度的人:**当使用需要唯一键的地图时,`count`和`find`的速度几乎相同。(1)如果不需要元素来维护特定顺序,请使用[std :: unordered_map](https://en.cppreference.com/w/cpp/container/unordered_map),该元素具有[near-constant ](/sf/ask/193995791/)查找,在存储多对时非常有用。(2)如果要使用该值(如果存在),请存储:: find的结果,并使用迭代器防止2次查找:`auto it = m.find(“ f”); if(it!= m.end()){/ *使用它-&gt; second * /}` (5认同)

Dav*_*dRR 287

要检查映射中是否存在特定键,请使用count以下方法之一使用成员函数:

m.count(key) > 0
m.count(key) == 1
m.count(key) != 0
Run Code Online (Sandbox Code Playgroud)

文档map::find说:"其他部件的功能,map::count可以用来只检查一个特定的键是否存在."

所述文档map::count表示:"因为在地图容器中的所有元素是唯一的,该函数只能返回1(如果该元件被发现),或零(否则)".

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

value = m.at(key)
Run Code Online (Sandbox Code Playgroud)

map :: operator []不同,map::at如果指定的键不存在,则不会在映射中创建新键.

  • 如果要执行这两项操作,请检查它是否存在,然后对其执行某些操作.请改用"find".`find`返回的迭代器的`second`属性可以用来检索键的值.如果使用`count`然后`at`或`operator []`,那么当你只使用一个时,你正在执行两个操作. (30认同)
  • @jv110当遇到从`int`到`bool`的强制转换时,Microsoft C++编译器[发出警告](http://stackoverflow.com/q/4968033/1497596).虽然还有其他C++编译器没有发出类似的警告,但我更喜欢使用[显式比较](http://stackoverflow.com/a/4968060/1497596)来明确意图并提高可读性.注意其他语言如C#[禁止这种隐式转换](http://stackoverflow.com/a/6571505/1497596)以防止引入细微编程错误的可能性. (6认同)
  • 你不需要做 &gt; 0, == 1 或 != 0; 这就是 C++ 在 if 语句中所做的精确检查(条件!= 0),因此您可以只使用 `if(m.count(key))` (2认同)
  • @Mazeryt不,`std::map::count`实际上是[对数](https://en.cppreference.com/w/cpp/container/map/count)。这是因为 [C++ std::map](https://en.cppreference.com/w/cpp/container/map) 是有序映射,因此它不使用哈希表。然而,C++ 标准库也有 `std::unordered_map`,其中 `std::unordered_map::count` 通常是 [O(1)](https://en.cppreference.com/w/cpp/container/无序_映射/计数)。请参阅 [DavidRR 的链接](/sf/ask/193995791/) 了解为什么 std::unordered_map::count 也不总是 O(1)。 (2认同)

Tho*_*ini 36

你可以使用.find():

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

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


Den*_*kov 21

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我想我会说:最后。 (12认同)
  • 伟大的!还好我向下滚动到这里。也许编辑接受的答案并将其添加到其中? (2认同)

aJ.*_*aJ. 14

m.find == m.end() // not found 
Run Code Online (Sandbox Code Playgroud)

如果您想使用其他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";
Run Code Online (Sandbox Code Playgroud)


Ste*_*sop 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来说它更有趣.


小智 6

map<string, string> m;
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

在你的问题中,错误是由坏operator<<过载引起的,因为p.firstmap<string, string>,你无法打印出来。尝试这个:

if(p.first != p.second) {
    cout << p.first->first << " " << p.first->second << endl;
}
Run Code Online (Sandbox Code Playgroud)


Lam*_*age 6

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

当然,如果你想变得更漂亮,你总是可以模板化一个函数,它也接受一个找到的函数和一个未找到的函数,就像这样:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

    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; });
Run Code Online (Sandbox Code Playgroud)

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


WBu*_*uck 6

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

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..
}
Run Code Online (Sandbox Code Playgroud)