L'algoritmo di hash esatto non è specificato dallo standard, pertanto i risultati variano. L'algoritmo utilizzato da VC10 non sembra prendere in considerazione tutti i caratteri se la stringa è più lunga di 10 caratteri; it anticipi con un incremento di 1 + s.size()/10
. Questo è legale, sebbene da un punto di vista di QoI, piuttosto deludente; tali codici hash sono noti per prestazioni molto scarse per alcuni set di dati tipici (come gli URL ).Mi piacerebbe vivamente di sostituirlo con uno un hash FNV o una basata su un primo di Mersenne:
FNV hash:
struct hash
{
size_t operator()(std::string const& s) const
{
size_t result = 2166136261U ;
std::string::const_iterator end = s.end() ;
for (std::string::const_iterator iter = s.begin() ;
iter != end ;
++ iter) {
result = (16777619 * result)
^static_cast< unsigned char >(*iter) ;
}
return result ;
}
};
Mersenne Prime hash:
struct hash
{
size_t operator()(std::string const& s) const
{
size_t result = 2166136261U ;
std::string::const_iterator end = s.end() ;
for (std::string::const_iterator iter = s.begin() ;
iter != end ;
++ iter) {
result = 127 * result
+ static_cast< unsigned char >(*iter) ;
}
return result ;
}
};
(La FNV l'hash è presumibilmente migliore, ma l'hash prime Mersenne sarà più veloce su molte macchine, perché moltiplicare per 127 è spesso molto più veloce della moltiplicazione per 2166136261.)
fonte
2011-11-01 16:44:03
Quale compilatore e versione? – Joe
@Joe Uso MSVC10 – relaxxx
@relaxxx: MSVC10 sarà probabilmente l'ultimo a fornire un'implementazione C++ completa (se mai lo sarà). se vuoi un'implementazione funzionante, la più completa è clang. puoi anche provare il gcc più popolare. – Dani