2014-10-23 14 views
7

Ho std::multimap<string, MyObject*> dataMap; dove le chiavi sono MyObject.name e tutti i MyObjects sono memorizzati in un std::vector<MyObject>.Come eseguire un'iterazione attraverso una multimappa e stampare i valori raggruppati per chiave?

Dopo aver riempito la mappa, devo stampare il contenuto di dataMap raggruppato dalla stessa chiave, in cui prima ho bisogno del numero delle stesse chiavi con l'aiuto di dataMap.count(MyObject.name) e quindi tutti i valori con questa chiave.

Stavo pensando di utilizzare due for loops dove i primi itera Loop Through "i nomi dei gruppi chiave" e conta tutte le chiavi che appartengono a questo gruppo, e le altre for loop scorre tutte le chiavi in ​​certo gruppo e stampa i MyObject.information

for(//iterate through group key names){ 
    //print number of key occurences 
    for(//iterate through a certain group{ 
     //print MyObject.information for all the keys in a group 
    } 

} 

Il problema è che non so davvero come implementare questo o piuttosto come userò gli iteratori alla mia volontà. Qualche idea?

EDIT: dai link forniti Ho creato questo

for(std::multimap<string, MyObject*>::const_iterator itUnq = dataMap.cbegin(); 
    itUnq != dataMap.cend(); itUnq = dataMap.upper_bound(itUnq->first)){ 

     std::cout << dataMap.count(itUnq->second->name) 
        << std::endl; 

     std::pair <std::multimap<string, MyObject*>::const_iterator, 
        std::multimap<string, MyObject*>::const_iterator> groupRange; 
     groupRange = dataMap.equal_range(itUnq->second->code); 

     //iterate through keys inside the group 
     for(std::multimap<string, MyObject*>::const_iterator itGroup = groupRange.first; 
      itGroup != groupRange.second; ++itGroup){ 

      std::cout << itGroup->second->information 

     } 

Commenti?

+0

Che cosa significa "tutti i MyObject sono memorizzati in un file std :: vector "? Hai anche detto che le chiavi 'dataMap' erano' * MyObject' 0 u.e. solo un puntatore a MyObject ... e una potenziale perdita di memoria, giusto? – doctorlove

+0

Significa che quando sto riempiendo la mappa sta leggendo dal vettore dove la chiave è 'MyObject.name' e il valore è l'oggetto stesso. Ho usato un puntatore per evitare di copiare l'oggetto – TheGuyWithStreetCred

+1

Forse guardate [std :: multimap :: equal_range] (http://www.cplusplus.com/reference/map/multimap/equal_range/). – Galik

risposta

6

Da quanto ho capito del problema, è possibile implementarlo utilizzando std::multimap::equal_range.

Qualcosa di un po 'come questo:

#include <map> 
#include <ctime> 
#include <string> 
#include <vector> 
#include <iostream> 
#include <algorithm> 

struct MyObject 
{ 
    std::string name; 
    int information; 

    MyObject(const std::string& name, int information) 
    : name(name), information(information) {} 
}; 

int main() 
{ 
    std::srand(std::time(0)); 

    std::vector<MyObject> dataVec; 
    std::multimap<std::string, MyObject*> dataMap; 

    // Give each object a random letter 
    // between A-J as a name and some data 
    for(auto i = 0; i < 10; ++i) 
     dataVec.emplace_back(std::string(1, 'A' + std::rand() % 10), i); 

    // Fill dataMap from dataVec 
    for(auto&& data: dataVec) 
     dataMap.emplace(data.name, &data); 

    // Select the correct type for calling the equal_range function 
    decltype(dataMap.equal_range("")) range; 

    // iterate through multimap's elements (by key) 
    for(auto i = dataMap.begin(); i != dataMap.end(); i = range.second) 
    { 
     // Get the range of the current key 
     range = dataMap.equal_range(i->first); 

     // Now print out that whole range 
     for(auto d = range.first; d != range.second; ++d) 
      std::cout << d->first << ": " << d->second->information << '\n'; 
    } 
} 

Run It Here

se questo non è esattamente ciò che si vuole, forse sarà ancora vi darà idee su come risolvere il problema specifico.

+0

Questo ha aiutato a chiarire alcune cose, grazie :) – TheGuyWithStreetCred

+0

@ user2202368 Non ho notato che hai pubblicato una soluzione nella domanda.L'unica vera differenza che posso vedere è che la mia versione usa il 'equal_range()' restituito per selezionare l'iteratore successivo nel ciclo esterno, che è probabilmente leggermente più efficiente del calcolo di 'upper_bound()' di nuovo. – Galik