6

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

4

2 回答 2

1

如何使用任何对象作为键:

  1. 将对象序列化为字节数组(对于整数数组,只需按原样使用二进制数据)
  2. 计算加密哈希(MD5 或 SHA)
  3. 将加密哈希转换为指纹值(例如将其前 64 位转换为 uint64_t)
  4. 将此指纹用作地图键

缺点是您可能需要以某种方式解决冲突。

于 2013-06-14T17:05:17.157 回答
1

我可以把它改成这个吗?

首先,您的数组初始化是错误的:

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

由于std::array没有带有std::initializer_listas 参数的构造函数。因此,第一级用于初始化对象,第二级用于初始化对象中的数组。

其次,来自参考

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

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

因此,您应该通过std::pair(或可转换为 的东西std::pair),例如:

closelist.insert({sn,24});

或者,更简单:

closelist[sn] = 24;
于 2013-06-14T15:47:08.673 回答