Quelle est la différence entre std :: multimap <key, value> et std :: map <key, std :: set <value>>

Réponses:

52

La multi-carte stocke des paires de (clé, valeur) où la clé et la valeur peuvent apparaître plusieurs fois.

Le map<key, set<value>>ne stockera chaque valeur qu'une seule fois pour une clé spécifique. Pour ce faire, il devra pouvoir comparer les valeurs, pas seulement les clés.

Cela dépend de votre application si les valeurs qui se comparent sont équivalentes ou si vous souhaitez quand même les stocker séparément. Peut-être qu'ils contiennent des champs différents mais qui ne participent pas à la comparaison de l'ensemble.

Bo Persson
la source
5
Ainsi, un std :: multimap <clé, valeur> est comme un std :: map <clé, std :: multiset <valeur>>, la différence entre eux est que les valeurs ultérieures sont triées. Est-ce correct?
大 宝剑
2
Non, std::multimap<key, value>permet à la même clé d'apparaître plusieurs fois alors que std::map<key, whatever>requiert l'unicité de key.
Yixing Liu
74

A std::mapest un conteneur associatif, qui vous permet d'avoir une clé unique associée à votre valeur de type. Par exemple,

void someFunction()
{
    typedef std::map<std::string, int> MapType;
    MapType myMap;

    // insertion
    myMap.insert(MapType::value_type("test", 42));
    myMap.insert(MapType::value_type("other-test", 0));

    // search
    auto it = myMap.find("test");
    if (it != myMap.end())
        std::cout << "value for " << it->first << " is " << it->second << std::endl;
    else
        std::cout << "value not found" << std::endl;
}

A std::multimapest égal à a std::map, mais vos clés ne sont plus uniques. Par conséquent, vous pouvez trouver une gamme d'articles au lieu de trouver un seul article unique. Par exemple,

void someFunction()
{
    typedef std::multimap<std::string, int> MapType;
    MapType myMap;

    // insertion
    myMap.insert(MapType::value_type("test", 42));
    myMap.insert(MapType::value_type("test", 45));
    myMap.insert(MapType::value_type("other-test", 0));

    // search
    std::pair<auto first, auto second> range = myMap.equal_range("test");
    for (auto it = range.first; it != range.second; ++it)
        std::cout << "value for " << it->first << " can be " << it->second << std::endl;
}

Le std::setest comme un std::map, mais il ne stocke pas une clé associée à une valeur. Il stocke uniquement le type de clé et vous assure qu'il est unique dans l'ensemble.

Vous avez également le std::multiset, qui suit le même modèle.

Tous ces conteneurs fournissent un accès O (log (n)) avec leur find / equal_range.

typedef
la source
6
En fonction multimap, cette ligne std::pair<auto first, auto second> range = myMap.equal_range("test");ne fonctionne pas, car error: 'auto' not allowed in template argument. Utilisez const auto range = myMap.equal_range("test")plutôt.
vancexu
2
type de carte? Ne devrait-il pas être MapType sur la ligne 4?
lolololol ol
je
idclev 463035818
1
ahah, cppbuzz racle StackOverflow ou quoi ?, J'ai écrit cette réponse moi-même il y a des années alors que je codais encore quotidiennement en C ++. Et il y a bien une faute de frappe ligne 4, merci @lololololol
typedef
1
(et leur copier / coller a échoué, ils n'affiche même pas les types dans le modèle std :: map déclaration: std :: map <std :: string, int>)
typedef
13
map::insert

Étant donné que les mapconteneurs n'autorisent pas les valeurs de clé en double, l'opération d'insertion vérifie pour chaque élément inséré si un autre élément existe déjà dans le conteneur avec la même valeur de clé, si tel est le cas, l'élément n'est pas inséré et sa valeur mappée n'est en aucun cas modifiée.

d'autre part

multimap::insert 

peut insérer n'importe quel nombre d'éléments avec la même clé.

http://www.cplusplus.com/reference/stl/map/
http://www.cplusplus.com/reference/stl/multimap/

Luka Rahne
la source
Bon lien à la fois sur la différence et sur son fonctionnement en interne. lien
Rndp13
10

Ce dernier nécessite que les valeurs puissent être ordonnées (via operator<ou une fonction de comparaison), le premier ne le fait pas.

Björn Pollex
la source
Il semblerait que l'opérateur <fonctionne de la même manière sur la carte ou sur la carte multi-cartes? en.cppreference.com/w/cpp/container/map/operator_cmp
johnbakers
Oui, mais ma réponse se référait à l'ordre des valeurs. Supposons que vous ayez un type Tsans ordre. Vous pouvez l'utiliser pour créer un fichier std::multimap<U, T>, mais vous ne pouvez pas l'utiliser pour créer un fichier std::map<U, std::set<T> >.
Björn Pollex