2009-05-23 7 views
1

J'ai utilisé la liste pour placer les villes dans un voyage. Ensuite, je parcourir sur la liste pour afficher l'itinéraire du voyage. Je voudrais accéder à les villes par le nom plutôt que par l'ordre de voyage. Donc, je pensais que je pouvais utiliser une carte plutôt qu'une liste, mais la clé détermine l'ordre. Je voudrais quand même contrôler l'ordre de la séquence mais pouvoir accéder aux entrées par une clé.Commander comme une liste mais l'accès par une clé?

Ces caractéristiques peuvent-elles être combinées? Y a-t-il une manière standard d'adresser ceci ceci?

#include <list> 
#include <iostream> 
struct City{ 
    City(std::string a_n, int a_d):name(a_n), duration(a_d){} 
    std::string name; 
    int duration; 
}; 
int main(){ 
    std::list<City*> trip; 
    trip.push_back(new City("NY", 5)); 
    trip.push_back(new City("LA", 2)); 
    for (std::list<City*>::iterator ii=trip.begin(); ii!=trip.end(); ++ii) 
     std::cout << (*ii)->name << " for " << (*ii)->duration << " days." <<std::endl; 
} 
+1

Youn ne doit PAS utiliser de balises HTML pour mettre en forme des publications SO. Pour mettre en forme le code, sélectionnez tout le code avec la souris et tapez Ctrl-K. –

+0

Neil - Quel est le problème avec les balises HTML? Si cela vous choque, n'hésitez pas à modifier le message et à le corriger. Pas besoin d'être en colère à ce sujet –

Répondre

5

Souvent, vous aurez besoin de composer plusieurs listes et cartes. La manière la plus courante consiste à stocker un pointeur vers la carte de recherche Villes par ville, à partir des pointeurs de votre liste. Ou vous pouvez utiliser une classe comme Boost.MultiIndex pour faire ce que vous voulez dans ce que je dirais est beaucoup plus propre. Il évolue également beaucoup mieux et il y a beaucoup moins de code de plaque de chaudière si vous voulez ajouter de nouveaux index. Il est également généralement more space and time efficient

typedef multi_index_container< 
    City, 
    indexed_by< 
    sequenced<>, //gives you a list like interface 
    ordered_unique<City, std::string, &City::name> //gives you a lookup by name like map 
    > 
> city_set; 
1

Créer une map<string,int> m;, où les valeurs sont des indices à un vector<City>, par exemple m["NY"] == 0 et m["LA"] == 1.

+1

Accéder à une liste via un index est une opération coûteuse. Une carte de nom à itérateur serait plus raisonnable. –

+0

J'ai changé 'list' en' vector' dans ma réponse. Merci d'avoir soulevé cette question. – pts

0

Utilisez deux collections:

  • Une liste pour stocker les objets réels dans l'ordre que vous êtes intéressé par
  • Une carte à carte des noms aux objets..
0

La meilleure solution est d'utiliser Boost.MultiIndex, bien que ce soit un peu plus impliqué. Malheureusement, je n'ai pas le temps maintenant de fournir un exemple de code; Pardon.

Questions connexes