2013-10-05 3 views
24

Obecnie mam dużo kodu, który wygląda tak:Jaki jest najszybszy sposób wstawiania/aktualizowania std :: unordered_map elementów bez użycia atrybutu if?

std::unordered_map<int,int> my_dict; 
. 
. 
. 
// If the key does exist in the dictionary 
if(my_dict.count(key) == 1){ 
    my_dict[key] = value; 
} 

// If its a new key 
else{ 
    my_dict.insert(std::make_pair(key,value)); 
} 

Czy jest jakiś sposób mogę to przyspieszyć tylko przez nadpisanie wartości za każdym razem?

+0

Wygląda należy użyć map – billz

+0

@billz chcę O (1) czas wstawiania? Nie chcę drzewa O log (N) – user997112

+2

[] to robi. http://www.cplusplus.com/reference/unordered_map/unordered_map/operator[]/ Oczywiście złożoność musi być liniowa. Jeśli chcesz mniej czasu na wstawienie, użyj mapy – janoliver

Odpowiedz

35

Wystarczy zrobić (na map i unordered_map)

mydict[key]=value; 
+0

użycie 'if-else' będzie szybsze wtedy i tylko wtedy, gdy domyślna konstrukcja' value' jest bardzo kosztowna. Jednak w większości przypadków 'operator []' wykonuje zadanie. – letsBeePolite

13

myślę, że może to być najszybciej jak to:

auto it = my_dict.find(key); 
if(it != my_dict.end()) { 
    *it = value; 
} 
else { 
    my_dict.insert(std::make_pair(key,value)); 
} 

że sposób nie modyfikować strukturę unordered_map jeśli key już istnieje i masz tylko jeden odnośnika.


Innym rozwiązaniem w przypadku, gdy nie potrzeba/dostęp value potem:

my_dict[key] = std::move(value); 

To może być lepiej w przypadkach gdy cesja value jest drogie i korzyści z move-semantyki.

+1

Dlaczego to zrobić, jeśli 'operator []' już to robi? – us2012

+3

@ us2012 Głównie, ale w przypadku wstawiania najpierw wstawia domyślną skonstruowaną wartość, a następnie ją przypisuje. Powyższe unika tego nad głową. –

+3

Zrobiłbym poważny pomiar prostego przypadku ('foo [klucz] = wartość;') zanim przejdę tą trasę. – Joe