Jak sprawdzić czy dany klucz istnieje w C++ std:: map

Próbuję sprawdzić czy dany klucz jest na mapie i jakoś nie mogę tego zrobić:

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

Więc jak Mogę wydrukować to, co jest w p?

Author: Antonio, 2009-12-21

14 answers

Użycie map::find

if ( m.find("f") == m.end() ) {
  // not found
} else {
  // found
}
 762
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-28 09:05:58

Aby sprawdzić, czy dany klucz na mapie istnieje, użyj funkcji member count w jeden z następujących sposobów:

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

Dokumentacja dla map::find mówi: "inna funkcja member, map::count, może być użyta do sprawdzenia, czy dany klucz istnieje."

Dokumentacja dla map::count mówi: "ponieważ wszystkie elementy w kontenerze mapy są unikalne, funkcja może zwrócić tylko 1 (Jeśli element zostanie znaleziony) lub zero (w przeciwnym razie)."

Aby pobrać wartość z Mapa za pomocą klucza, o którym wiesz, że istnieje, użyj map:: at :

value = m.at(key)

W przeciwieństwie do map:: operator[], map::at nie utworzy nowego klucza na mapie, jeśli podany klucz nie istnieje.

 329
Author: DavidRR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-03 16:10:00

C++20 daje nam std::map::contains, aby to zrobić.

#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";
    }
}
 75
Author: Denis Sablukov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-15 14:06:51

Możesz użyć .find():

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

if (i == m.end()) { /* Not found */ }
else { /* Found, i->first is f, i->second is ++-- */ }
 41
Author: Thomas Bonini,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-21 12:57:27

C++17 uprościłem to nieco bardziej za pomocą If statement with initializer. W ten sposób możesz zjeść swoje ciasto i je zjeść.

if ( auto it{ m.find( "key" ) }; it != std::end( m ) ) 
{
    // Use `structured binding` to get the key
    // and 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..
}
 16
Author: WBuck,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-22 12:48:40
m.find == m.end() // not found 

Jeśli chcesz użyć innego API, znajdź go dla 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";
 15
Author: aJ.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-21 13:08:12

Myślę, że chcesz map::find. Jeśli {[1] } jest równe m.end(), to klucz nie został znaleziony. W przeciwnym razie find zwraca iterator wskazujący na znaleziony element.

Błąd wynika z tego, że p.first jest iteratorem, który nie działa przy wstawianiu strumienia. Zmień ostatnią linię na cout << (p.first)->first;. p jest parą iteratorów, p.first jest iteratorem, p.first->first jest łańcuchem kluczy.

Mapa może mieć tylko jeden element dla danego klucza, więc equal_range nie jest zbyt przydatna. Jest zdefiniowana dla mapy, ponieważ jest zdefiniowana dla wszystkich kontenerów asocjacyjnych, ale jest to o wiele bardziej interesujące dla multimap.

 12
Author: Steve Jessop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-21 13:14:53
map<string, string> m;

Zaznacz klucz exist or not, and return number of exists( 0/1 in map):

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

Sprawdź czy klucz istnieje czy nie i zwróć iterator:

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

W twoim pytaniu, błąd spowodowany złym przeciążeniem operator<<, Ponieważ p.first jest map<string, string>, nie możesz go wydrukować. spróbuj tego.:

if(p.first != p.second) {
    cout << p.first->first << " " << p.first->second << endl;
}
 4
Author: hustljian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-24 13:29:24
template <typename T, typename Key>
bool key_exists(const T& container, const Key& key)
{
    return (container.find(key) != std::end(container));
}

Oczywiście, jeśli chcesz uzyskać więcej, zawsze możesz wybrać funkcję, która również wzięła funkcję znalezioną i funkcję nie znalezioną, coś w tym stylu:

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

I użyj go w ten sposób:

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

Minusem tego jest wymyślenie dobrej nazwy, "find_and_execute" jest niezręczne i nie mogę wymyślić nic lepszego z czubka głowy...

 4
Author: Lambage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-20 13:29:33

Bądź ostrożny w porównywaniu wyników znalezionych z końcem, jak dla mapy "m" , ponieważ wszystkie odpowiedzi mają done above map:: iterator i = m. find ("f");

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

Nie należy próbować wykonywać żadnych operacji, takich jak drukowanie klucza lub wartości za pomocą iteratora i, jeśli jest równy m. end (), w przeciwnym razie doprowadzi to do błędu segmentacji.

 3
Author: Invictus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-11 19:27:41

Porównując kod std::map:: find i std:: map:: count, powiedziałbym, że pierwszy może przynieść pewną przewagę wydajności:

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);
    }
 0
Author: Hope,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-23 08:37:30

Wiem, że to pytanie ma już kilka dobrych odpowiedzi, ale myślę, że moje rozwiązanie jest warte podzielenia się.

Działa zarówno dla std::map jak i std::vector<std::pair<T, U>> i jest dostępny z 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;
    }
}
 0
Author: NutCracker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-15 21:45:06

Jeśli chcesz porównać parę map, możesz użyć tej metody:

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

Jest to przydatna technika.

 -5
Author: EmreS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-21 18:34:59
map <int , char>::iterator itr;
    for(itr = MyMap.begin() ; itr!= MyMap.end() ; itr++)
    {
        if (itr->second == 'c')
        {
            cout<<itr->first<<endl;
        }
    }
 -5
Author: Muhammad Ahmad Zafar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-15 02:02:19