web-dev-qa-db-fra.com

Fonction de hachage C ++ pour la chaîne dans unordered_map

Il semble que C++ n'ait pas de fonction de hachage pour les chaînes dans la bibliothèque standard. Est-ce vrai?

Quel est un exemple pratique d'utilisation d'une chaîne comme clé dans un unordered_map qui fonctionnera avec n'importe quel compilateur c ++?

33
MirroredFate

C++ STL fournit un modèle spécialisations of std::hash pour les différentes classes de chaînes. Vous pouvez simplement spécifier std::string comme type de clé pour std::unordered_map:

#include <string>
#include <unordered_map>

int main()
{
    std::unordered_map<std::string, int> map;
    map["string"] = 10;
    return 0;
}
28
awesoon

J'ai rencontré ça aujourd'hui (en fait avec wstring, pas string, mais c'est la même chose): utiliser wstring comme clé dans un unordered_map génère une erreur indiquant qu'aucune fonction de hachage n'est disponible pour ce type.

La solution pour moi a été d'ajouter:

#include <string>

Croyez-le ou non, sans l'inclusion, j'avais toujours le type wstring disponible mais apparemment PAS les fonctions auxiliaires comme le hachage. L'ajout simple de l'inclusion ci-dessus l'a corrigé.

18
Dave

En fait, il y a std::hash<std::string>

Mais voici comment utiliser une autre fonction de hachage:

struct StringHasher {
    size_t operator()(const std::string& t) const {
          //calculate hash here.
    }
}

unordered_map<std::string, ValueType, StringHasher>
14
RiaD

Si vous avez un CustomType et que vous souhaitez vous connecter à l'infrastructure STL, c'est ce que vous pourriez faire.

namespace std
{
//namespace tr1
//{
    // Specializations for unordered containers

    template <>
    struct hash<CustomType> : public unary_function<CustomType, size_t>
    {
        size_t operator()(const CustomType& value) const
        {
            return 0;
        }
    };

//} // namespace tr1

template <>
struct equal_to<CustomType> : public unary_function<CustomType, bool>
{
    bool operator()(const CustomType& x, const CustomType& y) const
    {
        return false;
    }
};

} // namespace std

Si vous souhaitez ensuite créer disons un std::unordered_map<CustomType> la STL trouvera les hash et equal_to fonctionne sans que vous ayez à faire plus avec le modèle. C'est ainsi que j'aime écrire mon comparateur d'égalité personnalisé qui prend en charge les structures de données non ordonnées.

8
John Leidegren

Dans mon cas, c'était vraiment une distraction.

J'avais un type X pour lequel j'ai implémenté le hachage pour const & X an utilisé quelque part avec

std::unordered_map<const X, int> m_map;

Ensuite, je voulais avoir une autre carte dont les clés sont du type X et j'ai fait:

std::unordered_map<X, int> map_x;

Notez le MANQUE de const sur le deuxième cas.

0
sergiol