web-dev-qa-db-fra.com

Quelle est la meilleure façon d'utiliser deux clés avec un std :: map?

J'ai un std :: map que j'utilise pour stocker des valeurs pour les coordonnées x et y. Mes données sont très rares et je ne souhaite donc pas utiliser de tableaux ou de vecteurs, ce qui entraînerait un énorme gaspillage de mémoire. Mes données vont de -250000 à 250000 mais je n’aurai que quelques milliers de points au maximum. 

Actuellement, je crée un std :: string avec les deux coordonnées ("12x45") et je l’utilise comme clé. Cela ne semble pas être le meilleur moyen de le faire.

Mes autres pensées étaient d'utiliser un int64 et d'y insérer les deux int32 et de l'utiliser comme clé.

Ou utiliser une classe avec les deux coordonnées. Quelles sont les exigences pour une classe qui doit être utilisée comme clé?

Quelle est la meilleure façon de procéder? Je préfère ne pas utiliser une carte de cartes.

36
Roland Rabien

Utilisez std :: pair <int32, int32> pour la clé:

std::map<std::pair<int,int>, int> myMap;

myMap[std::make_pair(10,20)] = 25;
std::cout << myMap[std::make_pair(10,20)] << std::endl;
107
David Norman

J'ai l'habitude de résoudre ce genre de problème comme ceci:

struct Point {
    int x;
    int y;
};

inline bool operator<(const Point& p1, const Point& p2) {
    if (p1.x != p2.x) {
        return p1.x < p2.x;
    } else {
        return p1.y < p2.y;
    }
}
28
StackedCrooked

Quelles sont les exigences pour une classe qui doit être utilisée comme clé?

La mappe doit pouvoir indiquer si la valeur d’une clé est inférieure à celle d’une autre clé: par défaut, cela signifie que (clé1 <clé2) doit être une expression booléenne valide, c’est-à-dire que le type de clé doit implémenter l’opérateur "inférieur à".

Le modèle de carte implémente également un constructeur surchargé qui vous permet de transmettre une référence à un objet fonction du type key_compare, qui peut implémenter l'opérateur de comparaison: afin que la comparaison puisse également être implémentée en tant que méthode de cet objet fonction externe. avoir besoin d'être cuit à n'importe quel type de votre clé est de.

5
ChrisW

Boost a un conteneur de carte qui utilise un ou plusieurs index.

Carte multi-index

3
DeadHead

Cela va farcir plusieurs clés entières dans un grand entier, dans ce cas, un _int64. Il se compare comme un _int64, AKA long long (La déclaration de type la plus laide jamais. Short court court, ne serait que légèrement moins élégante. Il y a 10 ans, elle s'appelait vlong. Bien mieux. Voilà pour le "progrès"), donc aucune comparaison possible. la fonction est nécessaire. 

#define ULNG  unsigned long
#define BYTE  unsigned char
#define LLNG  long long 
#define ULLNG unsigned long long

// --------------------------------------------------------------------------
ULLNG PackGUID(ULNG SN,  ULNG PID, BYTE NodeId) {
    ULLNG CompKey=0;

    PID = (PID << 8) + NodeId;
    CompKey = ((ULLNG)CallSN << 32) + PID;

    return CompKey;
}

Ayant fourni cette réponse, je doute que cela fonctionne pour vous, car vous avez besoin de deux touches distinctes pour naviguer dans les 2 dimensions, X et Y. 

Par contre, si vous avez déjà la coordonnée XY et souhaitez simplement associer une valeur à cette clé, cela fonctionne de manière spectaculaire, car une comparaison _int64 prend le même temps que tout autre entier sur les puces Intel X86: une horloge. 

Dans ce cas, la comparaison est 3 fois plus rapide sur cette clé synthétique, par rapport à une clé triple. 

Si je l’utilisais pour créer une feuille de calcul peu remplie, j’utiliserais RX en utilisant deux arbres distincts, l’un imbriqué dans l’autre. Faites de la dimension Y "le boss" et cherchez d'abord la résolution de l'espace Y avant de passer à la dimension X. Les feuilles de calcul sont plus hautes que larges, et vous voulez toujours que la 1ère dimension d'une clé composée ait le plus grand nombre de valeurs uniques. 

Cet arrangement créerait une carte pour la dimension Y qui aurait une carte pour la dimension X en tant que données. Lorsque vous atteignez une feuille dans la dimension Y, vous commencez à chercher sa dimension X pour la colonne de la feuille de calcul. 

Si vous souhaitez créer un système de feuille de calcul très puissant, ajoutez une dimension Z de la même manière et utilisez-la pour, par exemple, des unités organisationnelles. C’est la base d’un système très puissant de budgétisation, de prévision et de comptabilité, qui permet aux unités administratives d’avoir beaucoup de comptes fastueux pour suivre les dépenses administratives et autres, sans que ces comptes prennent de la place pour des unités fonctionnelles ayant leurs propres types. des détails à suivre. 

1
user1899861

Utilisez std :: pair. Mieux même, utilisez QHash<QPair<int,int>,int> si vous avez beaucoup de ces mappages.

0
MadH