2011-08-22 16 views
11

Ho bisogno di specializzare la funzione di hash per unordered_map in modo da poter utilizzare i vettori int come chiavi. I valori dell'array sono generalmente 0 o 1, ad es. int array = {0, 1, 0, 1}, ma tecnicamente non limitato.Funzione di hash C++ per un array int

Qualcuno può consigliare una buona funzione di hash in questo caso? In alternativa, posso sempre convertire l'array int in una stringa ed evitare la specializzazione. Ma sono preoccupato per le prestazioni poiché potrei avere diversi milioni di questi array.

+2

Utilizzare o imitare "intervallo di hash" di Boost. Si costruisce chiamando ripetutamente 'hash_combine', che è anche in Boost e dovrebbe essere nello standard. –

+0

Se si dispone di diversi milioni di questi array, suggerisco nuovi algoritmi/strutture dati ... – Blindy

+0

@Blindy Quali strutture dati suggeriresti? – gewizz

risposta

6

C++ TR1 contiene una funzione modello hash.

Se non lo hai ancora, puoi utilizzare Boost Hash.

Idea per un aiuto a portata di mano:

#include <boost/functional/hash.hpp> 

template <typename T, int N> 
    static std::size_t hasharray(const T (&arr)[N]) 
{ 
    return boost::hash_range(arr, arr+N); 
} 

Questo sarebbe (? Approssimativamente) equivalente a

size_t seed = 0; 
for (const T* it=arr; it!=(arr+N); ++it) 
    boost::hash_combine(seed, *it); 
return seed; 

Non dimenticare di applicare il funzionamento corretto confronto di uguaglianza, se si sta utilizzando questo hash per ricerca

+0

Penso che dovrebbe essere 'std :: size_t N' perché' std :: size_t' è garantito per essere in grado di rappresentare la dimensione dell'array più grande possibile, mentre 'int' potrebbe traboccare (a seconda del sistema). Inoltre, non è necessario che sia un tipo firmato. – outofthecave

+0

@outofthecave punti fiera. Tuttavia, unsigned è contagioso e questo lo rende ingombrante per gli offset (possono essere negativi, e 'N-10' si avvolge solo se' N <10'. Sorpresa!). Inoltre, gli array sono tipizzati staticamente a più di 2 ¹ elementi? Quelli sono rari. E tu non li raderesti spesso, se li avessi. – sehe

5

Prova a utilizzare la funzione di hash lookup8. Questa funzione è MOLTO veloce e buona.

int key[100]; 
int key_size=10; 
for (int i=0;i<key_size;i++) key[i]=i; //fill key with sample data 
ub8 hash=hash((ub8*)key, sizeof(key[0])*key_size, 0); 
+0

Questo non è C++. – Puppy

+9

Solitamente le funzioni di hash sono scritte in chiaro c. Puoi creare wrapper C++ per questo. – vromanov

+2

Di solito, le funzioni di hash sono scritte * nella lingua in cui si trova *. – Puppy

Problemi correlati