【问题标题】:Using lower_bound on nested map在嵌套地图上使用 lower_bound
【发布时间】:2016-04-24 10:05:24
【问题描述】:

我有一张看起来像的地图

map<string , map<int,int>>

字符串包含学生的姓名,嵌套映射包含 ID 作为键和年龄作为值。当我打印地图时,它会按应有的方式打印值。

但是,我想找一个 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 地图参考上找到有关此内容的信息,但一无所获。

【问题讨论】:

  • 这是一个奇怪的数据结构。一个学生,由他或她的名字识别,可以有多个 ID 和年龄?
  • 您是如何设法声明名为 class 的地图的?

标签: c++ dictionary


【解决方案1】:

以下代码可以解决您的问题:

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及以下的学生”,所以我们打印所有低于upper_bound的返回值的id。
停止条件是如果迭代器本身是x.second.begin(),这意味着现在我们没有任何比它小的id。


加上你的数据结构很奇怪,你应该有学生证作为你的主要索引。

map&lt;int, pair&lt;string,int&gt; &gt; 将是更合适的数据结构。 (假设大多数情况下都是唯一的 id)。
不过,使用 OOP 概念可以做得更好。

【讨论】:

  • 您不应该检查upper_bound 的返回值,以防它返回x.second.end()(即它不存在于地图中)?
  • 如果upper_bound 返回it=x.second.end(),那么prev(it) 将指向地图中的最后一个元素。所以我们打印所有的 id 直到 x.second.begin()
【解决方案2】:

您看到的可能是未定义的行为,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;       
    }     
}  

【讨论】:

  • 这不会产生预期的输出。当 some_number 为 0 时,它仍然打印 k1 = 1 1。预期的输出应该是无。
  • @RishitSanmukhani 我已经更新了,如果我没有忽略一些事情,它比我想象的要容易
猜你喜欢
  • 1970-01-01
  • 2021-04-18
  • 1970-01-01
  • 2019-01-10
  • 1970-01-01
  • 2018-06-17
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多