Jak sprawdzić, czy std :: map zawiera klucz bez wykonywania wstawiania?


Odpowiedzi:


305

Użyj my_map.count( key ); może zwrócić tylko 0 lub 1, co jest w istocie wynikiem logicznym, którego chcesz.

Alternatywnie my_map.find( key ) != my_map.end()działa też.


40
@John: To cuchnie przedwczesną optymalizacją. Na GCC (i jestem pewien, że większość rozsądnych systemów) map::countjest zaimplementowany jako find(__x) == end() ? 0 : 1;. Na multimapmajowym masz argumentu wydajności, ale to nie jest kwestia OP i nadal preferują elegancję.
Potatoswatter

42
Nie, argument przedwczesnej optymalizacji jest ważny tylko wtedy, gdy optymalizacja wymaga pewnego wysiłku, co w tym przypadku nie.
markh44

13
Nie prawda. Nie jest to przedwczesne, jeśli ułatwia to odczytanie kodu lub eliminuje niepotrzebne obciążenie. W tym przypadku, jeśli count () i tak jest zaimplementowana przez find (), to wywołanie find () bezpośrednio eliminuje wywołanie funkcji ... ergo, to dojrzała optymalizacja. Uważam, że użycie wywołania find () jest również bardziej oczywiste, ale to czysto osobiste preferencje.
Tim Keating,

9
Nie jest przedwczesną optymalizacją, aby zdać sobie sprawę z perfekcji funkcji bibliotecznych, zanim nabędziesz nawyku ich używania. W tym przypadku masz rację, to nie ma znaczenia, ale nie ma też najmniejszej różnicy stylistycznej między znalezieniem a policzeniem. Myślę, że zbyt daleko posuwasz się z retoryką „przedwczesnej optymalizacji”. Powinieneś wziąć wszystkie „bezpłatne” nawyki optymalizacyjne, które możesz znaleźć i wykorzystać je w codziennym rozwoju. To właśnie wtedy, gdy programiści wpadają w pułapkę płacenia kosztów za czytelność / czas programowania / itp., Wszystko dla niezmierzonych „zysków wydajności”, przedwczesna retoryka optymalizacyjna staje się właściwą radą.
VoidStar

10
Tak daleko, std powinno po prostu dodać cholerną has(k)/ contains(k)jak każdą inną rozsądną klasę mapy na planecie. Słaby projekt interfejsu. Podejście find () jest zbyt rozwlekłe, a count(k)podejście zdecydowanie nie ma równości semantycznej z has(k). W tym przypadku też nie jest find(k). Sprawdź liczbę wyświetleń tego pytania.
Jarrod Smith

46

Odpowiedź Potatoswatter jest w porządku, ale wolę użyć findlub lower_boundzamiast tego. lower_boundjest szczególnie przydatne, ponieważ zwrócony iterator może być później użyty do wstawienia z podpowiedzią, jeśli chcesz wstawić coś z tym samym kluczem.

map<K, V>::iterator iter(my_map.lower_bound(key));
if (iter == my_map.end() || key < iter->first) {    // not found
    // ...
    my_map.insert(iter, make_pair(key, value));     // hinted insertion
} else {
    // ... use iter->second here
}

Różni się to nieco od tego, jak mówi, że to robi… jedyna różnica polega na tym, że obliczenie valuemoże zostać pominięte, jeśli wstawianie jest niepotrzebne.
Potatoswatter

1
Jasne, rozumiem, że OP nie dba o wstawianie, więc lower_boundrozwiązanie oparte na a jest przesadą. W pewnym sensie właśnie wspomniałem o mojej odpowiedzi „dla kompletności”; jak powiedziałem, twój jest całkowicie wystarczający. :-)
Chris Jester-Young

4
Tak, to dobra odpowiedź iz niczym się nie zgadzam. Wystarczy wskazać związek z alternatywą inserta priori. W rzeczywistości istnieje inna różnica, jeśli używasz a multimap, lower_boundmetoda wstawia na początku równoważnego zakresu, podczas gdy zwykła insertmetoda dodaje do końca zakresu.
Potatoswatter

2
Nie odpowiedź na pytanie, ale moje kiepskie pytanie prowadzi mnie do właściwej odpowiedzi tutaj ... Muszę zrobić wstawienie / aktualizację. : D
Hunter-Orionnoir

1
@Hunter Czy możesz pokazać mi swój kod? Jeśli nie jest masywny, prawdopodobnie mogę go dla Ciebie przejrzeć.
Chris Jester-Young

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.