2016-04-24 117 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