2013-06-14 4 views
6

Привет, У меня был unordered_set для хранения моего 16 массива int, теперь мне нужно сохранить еще один int в качестве своего ведра. Интересно, могу ли я вставить массив в мой unordered_set, или я могу использовать тот же шаблон, который я использовал?C++ Как вставить массив в unordered_map в качестве ключа?

#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); 
} 

Могу я просто изменить его на это?

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); 
    } 

И я не мог понять шаблон, интересно, что такое "Н = Н * 31 + мясорубка (а [я]);"?

спасибо !!!

+0

_ «Интересно, что такое' h = h * 31 + hasher (a [i]); '' _ - В этой строке вы просто вычисляете хэш для своего массива. Что именно вы не понимаете? – soon

+0

@soon что такое 31? Я спросил об этом, и какой-то хороший парень дал мне этот шаблон ... – weeo

+0

'31' - это просто константа. Это зависит от ваших ограничений для элементов в массиве. – soon

ответ

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_list в качестве аргумента. Итак, первый уровень для инициализации объекта, второй для инициализации массива в объекте.

Во-вторых, из reference:

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; 
1

Как использовать любой объект в качестве ключа:

  1. сериализовать объект в массив байтов (для массива Интс просто использовать двоичные данные, как это)
  2. Compute криптографический хэш (MD5 или ША)
  3. Преобразование криптографический хэш в значение отпечатка пальца (например, подавать его первые 64 битов в uint64_t)
  4. использовать этот отпечаток пальца в виде карты ключа

disadvantag e - то, что вам может понадобиться разрешить конфликты.

+0

Обычно вы не используете криптографический хэш _unless_, который вам действительно нужен. Криптографические хеши вычислительно более интенсивно. Кроме того, поиск идеальной хэш-функции (без столкновений для вашего приложения) всегда является проблемой. В большинстве случаев стандартная реализация работает очень хорошо. –

Смежные вопросы