在嵌套映射上使用lower_bound

时间:2016-04-24 10:05:24

标签: c++ dictionary

我的地图看起来像

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

这确实打印了正确的学生姓名,但他们的身份证和年龄只是零或随机数,导致这种行为的原因是什么?它只在我打印时才有效。

我试图在cpp地图参考上找到这个,但一无所获。

2 个答案:

答案 0 :(得分: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都低于upper_bound的返回值。
停止条件是如果迭代器本身是x.second.begin(),那意味着现在我们没有任何小于它的id。

另外,您的数据结构很奇怪,您应该将学生ID作为主要索引。

map<int, pair<string,int> >将是更合适的数据结构。 (假设大多数情况下都是唯一的id) 虽然,你可以使用OOP概念做得更好。

答案 1 :(得分: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;       
    }     
}