2016-04-24 7 views
1

ich eine Karte haben, die Mit lower_bound auf verschachtelte Karte

map<string , map<int,int>> 

die Zeichenfolge enthält Namen eines Studenten, die verschachtelte Karte enthält ID als Schlüssel und das Alter als Wert wie

aussieht. Wenn ich die Karte drucke, werden die Werte wie gewünscht ausgedruckt.

Allerdings möchte ich einen Studenten mit einer bestimmten ID und niedriger finden. Ich habe versucht, mit lower_bound mit:

for(auto &x : class){  
    auto it = x.second.upper_bound(some_number); 
    for(; it != x .second.begin() ; --it){ 
     cout << x.first << " = " << << it -> first << " " <<it -> second << endl;  
    } 
} 

Diese in der Tat druckt richtige Namen von Studenten, aber ihre IDs und Alter sind nur Nullen oder Zufallszahlen, was dieses Verhalten verursacht? Es funktioniert, wenn ich es nur drucke.

Ich habe versucht, darüber auf cpp Kartenreferenz herauszufinden, aber nichts gefunden.

+0

Wäre es möglich, zu bekommen [Minimal, Complete, und prüfbare Beispiel] (http://stackoverflow.com/help/mcve) – JVApen

+2

Das ist eine seltsame Datenstruktur. Ein Student, identifiziert durch seinen oder ihren Namen, kann mehrere IDs und Alter haben? –

+0

Wie haben Sie es geschafft, eine Karte namens 'class' zu deklarieren? –

Antwort

2

folgenden Code löst Ihr Problem:

for(auto &x : Class){  
    auto it = x.second.upper_bound(some_number); 
    while(it!=x.second.begin()){ 
     it=prev(it); 
     cout<< x.first<< " = "<< it->first<< " "<< it->second<< endl; 
    } 
} 

Siehe std::map::upper_bound

oben code Was tut, ist, zuerst den Iterator mit id streng größer als some_number findet. Jetzt, da wir "Studenten mit einer bestimmten ID und niedriger" drucken wollen, drucken wir alle IDs niedriger als der Rückgabewert von upper_bound.
Die Abbruchbedingung ist, dass, wenn Iterator selbst x.second.begin() ist, das bedeutet, dass wir jetzt keine IDs kleiner als es haben.


Plus Ihre Datenstruktur ist seltsam, Sie sollten Student ID als Ihren primären Index haben.

map<int, pair<string,int> > wäre geeignetere Datenstruktur. (Angenommen, eindeutige IDs sind meistens der Fall).
Obwohl Sie OOP-Konzepte viel besser verwenden könnten.

+0

Sollten Sie den Rückgabewert von 'upper_bound' nicht überprüfen, falls 'x.second.end()' zurückgegeben wird (d. H. Es ist nicht in der Map vorhanden)? –

+0

Wenn "top_bound" 'it = x.second.end()' zurückgibt, zeigt 'prev (it)' auf das letzte Element in der Map. Also drucken wir alle IDs bis 'x.second.begin()' –

0

Was Sie sehen, ist wahrscheinlich undefiniertes Verhalten, std::map::upper_bound gibt unter bestimmten Bedingungen auch end iterator zurück und aus Ihrem Code sieht es nicht so aus, als würden Sie nach dieser Bedingung suchen. Auch sollten Sie nicht class Schlüsselwort als Variablenname für Ihre Karte verwenden, ich bin Preety sicher, dass es nicht kompiliert. Unten ist ein Beispielcode, der ohne UB und drucken Sie alle IDs kleiner als eine bestimmte Anzahl einschließlich dieser ID funktionieren sollte:

http://coliru.stacked-crooked.com/a/efae1ae4faa3e656

map< string , map<int,int>> classes ={ 
    { "k1", {{1,1},{2,2},{3,3}} } 
}; 

//int class; 

int some_number = 4; 
for(auto &x : classes){  
    auto it_num_end = x.second.upper_bound(some_number); // some numberis just variable that contains number 
    for(auto it = x.second.begin(); it != it_num_end ; ++it){ 
    cout << x.first << " = " << it -> first << " " <<it -> second << endl;  
    }  
} 
+0

Dies erzeugt nicht die beabsichtigte Ausgabe. Wenn some_number 0 ist, druckt es immer noch "k1 = 1 1". Die erwartete Ausgabe sollte keine sein. –

+0

@RishitSanmukhani Ich habe aktualisiert, wenn ich etwas nicht übersehen habe, ist es einfacher als ich dachte – marcinj

Verwandte Themen