Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ How to insert array to unordered_map as its key?

Hi I used to have a unordered_set to hold my 16 int array, now I need to store one more int as its bucket. I wonder if I can insert the array into my unordered_set, or can I use the same template I used to use?

#include <unordered_set>
#include <array>

namespace std
{
    template<typename T, size_t N>
    struct hash<array<T, N> >
    {
        typedef array<T, N> argument_type;
        typedef size_t result_type;

        result_type operator()(const argument_type& a) const
        {
            hash<T> hasher;
            result_type h = 0;
            for (result_type i = 0; i < N; ++i)
            {
                h = h * 31 + hasher(a[i]);
            }
            return h;
        }
    };
}

std::unordered_set<std::array<int, 16> > closelist;

int main()
{
    std::array<int, 16> sn = {1,2,3,4,5,6,0,8,9,10,11,12,13,14,7,15};
    closelist.insert(sn);
}

Can I just change it to this?

std::unordered_map<std::array<int, 16>,int > closelist;

    int main()
    {
        std::array<int, 16> sn = {1,2,3,4,5,6,0,8,9,10,11,12,13,14,7,15};
        closelist.insert(sn,24);
    }

And I couldn't understand the template, I wonder what is "h = h * 31 + hasher(a[i]);"?

Thank you!!!

like image 782
weeo Avatar asked Jun 14 '13 15:06

weeo


People also ask

Can unordered_map have vector as key?

Can Unordered_map have vector as key? unordered_map uses vector as the key You can use the following method if you'd like to make the best of STL. }; Note that you can use any kind of operation to generate a hash. You just need to be creative so that collisions are minimized.

How are keys stored in unordered_map?

unordered_map is an associated container that stores elements formed by the combination of a key value and a mapped value. The key value is used to uniquely identify the element and the mapped value is the content associated with the key. Both key and value can be of any type predefined or user-defined.

Does unordered map preserve insertion order?

No. It's called "unordered" for a reason. If you need to maintain an order of insertion, you've chosen an unsuitable data structure.

Are Keys sorted in unordered_map?

unordered_map is used to store elements as key,value pairs in non-sorted order.


2 Answers

Can I just change it to this?

Firstly, your array initialization is wrong:

std::array<int, 16> sn = {{1,2,3,4,5,6,0,8,9,10,11,12,13,14,7,15}};
//                        ^                                     ^

Since std::array has no constructor with std::initializer_list as argument. So, first level for initializing an object, second for initializing an array in the object.

Secondly, from reference:

std::pair<iterator,bool> insert( const value_type& value );

template <class P> 
std::pair<iterator,bool> insert( P&& value );

So, you should pass std::pair(or something, convertible to std::pair), for example:

closelist.insert({sn,24});

Or, simpler:

closelist[sn] = 24;
like image 89
awesoon Avatar answered Oct 16 '22 17:10

awesoon


How to use any object as a key:

  1. Serialize the object into a byte array (for an array of ints just use the binary data as it is)
  2. Compute the cryptographic hash (MD5 or SHA)
  3. Convert the cryptographic hash into a fingerprint value (for example cast its first 64 bits into uint64_t)
  4. Use this fingerprint as a map key

The disadvantage is that you might need to resolve collisions somehow.

like image 37
Andrey Tuganov Avatar answered Oct 16 '22 17:10

Andrey Tuganov