2016-04-24 167 views
1

上使用LOWER_BOUND我有一張地圖,看起來像嵌套地圖

map<string , map<int,int>> 

字符串中包含學生的名字,嵌套映射包含ID爲關鍵和年齡作爲價值。當我打印地圖時,它會按照它應該打印的值。

但是,我想找到一個具有特定ID和更低的學生。我嘗試使用LOWER_BOUND使用:

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;  
    } 
} 

這確實打印學生的姓名權,但他們的ID和年齡都只是零或隨機數,是什麼原因造成這種現象?它只適用於打印。

我試圖找出關於這個cpp地圖引用,但什麼都沒發現。

+0

有沒有可能拿到[最小,完整,可驗證的示例] (http://stackoverflow.com/help/mcve) – JVApen

+2

這是一個奇怪的數據結構。一名學生,通過他或她的名字確定,可以有多個ID和年齡? –

+0

你是如何設法聲明一個叫'class'的地圖的? –

回答

2

下面的代碼解決您的問題:

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; 
    } 
} 

參考std::map::upper_bound

不會是什麼上面的代碼,它最先找到的迭代器ID嚴格大於some_number更大。現在因爲我們想要打印「具有特定ID和更低ID的學生」,所以我們打印所有ID低於返回值upper_bound
停止條件是,如果迭代器本身爲x.second.begin(),這意味着現在我們沒有任何id小於它。


加上你的數據結構很奇怪,你應該有學生ID作爲你的主索引。

map<int, pair<string,int> >會更合適的數據結構。 (假設唯一的ID大多是這種情況)。
雖然使用OOP概念可以做得更好。

+0

當你返回'x.second.end()'(即它不在地圖中)時,你不應該檢查'upper_bound'的返回值嗎? –

+0

如果upper_bound返回'it = x.second.end()',那麼'prev(it)'將指向地圖中的最後一個元素。所以我們打印所有的id直到'x.second.begin()' –

0

你看到的可能是未定義的行爲,std::map::upper_bound返回也在一些條件下結束迭代器,並從你的代碼看起來不像你檢查這種情況。你也不應該使用class關鍵字作爲你映射的變量名,我確定它不能編譯。下面是一個示例代碼,應該沒有UB工作,打印所有ID小於包括這個ID的一些數字:

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

這不會產生預期的輸出。當some_number爲0時,它仍然打印'k1 = 1 1'。預期的輸出應該是沒有的。 –

+0

@RishitSanmukhani我已經更新了,如果我沒有忽略過比我想象的更容易的事情 – marcinj