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

社会主义新天地 提交于 2019-12-07 02:35:51

问题


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!!!


回答1:


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;



回答2:


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.



来源:https://stackoverflow.com/questions/17112024/c-how-to-insert-array-to-unordered-map-as-its-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!