Chodzi mi o to - wiemy, że std::map
elementy są posortowane według kluczy. Powiedzmy, że klucze są liczbami całkowitymi. Jeśli wykonam iterację od std::map::begin()
do std::map::end()
a for
, czy standard gwarantuje, że będę konsekwentnie przechodzić przez elementy z kluczami posortowane w kolejności rosnącej?
Przykład:
std::map<int, int> map_;
map_[1] = 2;
map_[2] = 3;
map_[3] = 4;
for( std::map<int, int>::iterator iter = map_.begin();
iter != map_.end();
++iter )
{
std::cout << iter->second;
}
Czy jest to gwarantowane do druku, 234
czy jest to zdefiniowana implementacja?
Powód z życia: mam klucz std::map
z int
kluczami. W bardzo rzadkich sytuacjach chciałbym powtórzyć wszystkie elementy, z kluczem, większym niż konkretna int
wartość. Tak, wygląda na to, że std::vector
byłby to lepszy wybór, ale zwróć uwagę na moje „bardzo rzadkie sytuacje”.
EDYCJA : Wiem, że elementy std::map
są posortowane… nie trzeba na to zwracać uwagi (dla większości odpowiedzi tutaj). Napisałem to nawet w swoim pytaniu.
Pytałem o iteratory i kolejność, gdy przechodzę przez kontener. Dzięki @Kerrek SB za odpowiedź.
źródło
map::upper_bound
aby znaleźć punkt do rozpoczęcia iteracji.Odpowiedzi:
Tak, to gwarantowane. Co więcej,
*begin()
daje najmniejszą i*rbegin()
największą elementu, określona przez operatora porównania i dwie kluczowe wartościa
ib
dla których wyrażenie!compare(a,b) && !compare(b,a)
jest prawdziwe są uważane za równe. Domyślną funkcją porównania jeststd::less<K>
.Porządkowanie nie jest szczęśliwą funkcją bonusową, ale jest raczej fundamentalnym aspektem struktury danych, ponieważ kolejność jest używana do określenia, kiedy dwa klucze są takie same (zgodnie z powyższą regułą) i do wydajnego wyszukiwania (zasadniczo binarny wyszukiwanie, które ma logarytmiczną złożoność w liczbie elementów).
źródło
std::unordered_map
ma bardziej wydajny czas wyszukiwania O (1). Zaletąstd::map
jest porządkowanie kluczy, ale nie wyszukiwanie.Gwarantują to wymagania dotyczące kontenerów asocjacyjnych w standardzie C ++. Np. Patrz 23.2.4 / 10 w C ++ 11:
i 23.2.4 / 11
źródło
Myślę, że istnieje zamieszanie w strukturach danych.
W większości języków a
map
jest po prostu AssociativeContainer: mapuje klucz do wartości. W „nowszych” językach jest to generalnie osiągane przy użyciu mapy mieszania, dlatego nie jest gwarantowana kolejność.Jednak w C ++ tak nie jest:
std::map
to posortowany kontener asocjacyjnystd::unordered_map
jest asocjacyjnym kontenerem opartym na tablicy skrótów wprowadzonym w C ++ 11Tak więc, aby wyjaśnić gwarancje przy zamówieniu.
W C ++ 03:
std::set
,std::multiset
,std::map
Istd::multimap
są zagwarantowane uporządkowane zgodnie z tymi przyciskami (i kryterium zestawie)std::multiset
istd::multimap
, norma nie narzuca żadnej gwarancji zamówienia na równoważne elementy (tj. takie, które porównują równe)W C ++ 11:
std::set
,std::multiset
,std::map
Istd::multimap
są zagwarantowane uporządkowane zgodnie z tymi przyciskami (i kryterium zestawie)std::multiset
istd::multimap
, norma narzuca, że równoważne elementy (te, które porównują równe sobie) są sortowane zgodnie z kolejnością wstawiania (pierwsze wstawione jako pierwsze)std::unordered_*
kontenery, jak sama nazwa wskazuje, nie są zamawiane. Przede wszystkim kolejność elementów może się zmienić, gdy kontener jest modyfikowany (po wstawieniu / usunięciu).Gdy Norma mówi, że elementy są uporządkowane w sposób, oznacza to, że:
Mam nadzieję, że to wyjaśni wszelkie nieporozumienia.
źródło
Tak,
std::map
jest to sortowany pojemnik, zamawiany przezKey
dostawcęComparator
. Więc jest to gwarantowane.To z pewnością możliwe.
źródło
Tak ... elementy w
std::map
mają ścisłą słabą kolejność, co oznacza, że elementy będą składać się z zestawu (tj. Nie będzie powtórzeń kluczy, które są „równe”), a równość jest określana przez testowanie na dowolnym dwa klucze A i B, jeśli klucz A jest nie mniejszy niż klucz B i B jest nie mniejszy niż klucz A, to klucz A jest równy kluczowi B.Mając to na uwadze, nie możesz poprawnie posortować elementów a,
std::map
jeśli słaba kolejność dla tego typu jest niejednoznaczna (w twoim przypadku, gdy używasz liczb całkowitych jako typu klucza, nie stanowi to problemu). Musisz być w stanie zdefiniować operację, która definiuje całkowitą kolejność według typu, którego używasz dla kluczy w swoimstd::map
, w przeciwnym razie będziesz mieć tylko częściowe zamówienie dla swoich elementów lub poset, który ma właściwość, w której A może nie być porównywalne z B. W tym scenariuszu zazwyczaj zdarza się, że będziesz w stanie wstawić pary klucz / wartość, ale możesz skończyć z zduplikowanymi parami klucz / wartość, jeśli przejdziesz przez całą mapę i / lub wykryjesz „brakujące” pary klucz / wartość podczas próby wykonaniastd::map::find()
określonej pary klucz / wartość na mapie.źródło
begin () może dać najmniejszy element. Ale to zależy od implementacji. Czy jest to określone w standardzie C ++? Jeśli nie, to takie założenie jest niebezpieczne.
źródło