2013-06-14 14 views
6

Witam Byłem kiedyś unordered_set do przechowywania mojej 16 tablicy int, teraz muszę przechowywać jeszcze jeden int jako jego wiadro. Zastanawiam się, czy mogę wstawić tablicę do mojego unordered_set, czy mogę użyć tego samego szablonu, którego używałem?C++ Jak wstawić tablicę do unordered_map jako jej klucz?

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

Czy mogę po prostu to zmienić?

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

I nie mogłem zrozumieć szablonu, zastanawiam się, co to jest "h = h * 31 + hasher (a [i]);"?

Dziękujemy!

+0

_ "Zastanawiam się, co to jest' h = h * 31 + hasher (a [i]); "" - W tej linii po prostu obliczyć hash dla swojej tablicy. Czego dokładnie nie rozumiesz? – soon

+0

@soon co to jest 31? Zapytałem o to i jakiś miły facet dał mi ten szablon ... – weeo

+0

'31' jest po prostu stałą. To zależy od ograniczeń dotyczących elementów w tablicy. – soon

Odpowiedz

1

Czy mogę po prostu to zmienić?

Po pierwsze, twój inicjalizacji tablicy jest źle:

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

Od std::array ma konstruktora z std::initializer_list jako argument. Pierwszy poziom do inicjalizacji obiektu, drugi do inicjalizacji tablicy w obiekcie.

Po drugie, z reference:

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

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

Więc należy przekazać std::pair (lub coś, cabrio do std::pair), na przykład:

closelist.insert({sn,24}); 

Albo prościej:

closelist[sn] = 24; 
1

Jak używać dowolnego obiektu jako klucz:

  1. serializacji obiektu do tablicy bajtów (dla tablicy int tylko korzystać z danych binarnych, jak to jest)
  2. obliczenia skrótu kryptograficznego (MD5 lub SHA)
  3. Konwersja skrótu kryptograficznego do wartości odcisku palca (na przykład rzucić swoje pierwsze 64 bity język uint64_t)
  4. używać tego odcisku palca jako mapa kluczowego

disadvantag e jest to, że być może trzeba jakoś rozwiązać kolizje.

+0

Zwykle nie używasz żadnego skrótu kryptograficznego _nie ma tego, czego naprawdę potrzebujesz. Kryptograficzne skróty są bardziej intensywne obliczeniowo. Dodatkowo, znalezienie idealnej funkcji skrótu (bez kolizji dla twojej aplikacji) jest zawsze wyzwaniem. W większości przypadków standardowa implementacja działa bardzo dobrze. –

Powiązane problemy