简体   繁体   中英

effectively use std::unordered_map to insert or increment value of a key

Given an unorder map M, a key K, an init val V. I want to set M[K] to V if K is not in M; ++M[K] if K is in M. (eg use a map to count occurrence of elements)

There are several ways to achieve this, but when we separate find and insert/increment into two steps, at least we need hash(K) twice (How to make hints help? I think hint helps only when K is in M); On the other hand, when we use member function insert_or_assign, we cannot set M[K] different according to whether K is in M.

Is there a better way?

The insert() member function returns a pair that contains an iterator and a bool; the iterator points either to the inserted pair or to the pair that already exists, and the bool tells you which it is (if true, a new map element was inserted; if false, the returned iterator points to something already present and the value was not changed).

Using this, you can put the element there if it wasn't or find it if it was there using single hash operation in all cases:

auto result = M.insert({ K, V });
if (!result.second) {
    // Element was already present; increment the value at the key K.
    ++(result.first->second);
}

I think I found a way to do this: try_emplace will return the iterator to M[K] when K is already in M. Then we just update M[K].

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM