在std :: map中,获取一个迭代器,指向不比键大的LAST元素

时间:2017-07-31 23:03:35

标签: c++

在提问之前:我理解std::map::lower_boundstd::map::upper_bound

的含义

问题:如何让迭代器指向不比键更大的LAST元素。

以下示例显示了lower_bound / upper_bound的当前行为。

但是,我想:

  • 传入" 20",20返回
  • 传入" 25",20返回

我如何实现这一目标?

#include <iostream>
#include <map>

int main ()
{
  std::map<int,char> mymap;
  std::map<int,char>::iterator itlow,itup;

  mymap[10]='a';
  mymap[20]='b';
  mymap[30]='c';
  mymap[40]='d';
  mymap[50]='e';

  itlow=mymap.lower_bound (20);  // itlow points to 'b'  
  std::cout << "lower_bound for 20:    " << itlow->first << " => " << itlow->second << '\n';

  itup=mymap.upper_bound (20);   // itup points to 'c'
  std::cout << "upper_bound for 20:    " << itup->first << " => " << itup->second << '\n';


  itlow=mymap.lower_bound (25);  // itlow points to 'c'  
  std::cout << "lower_bound for 25:    " << itlow->first << " => " << itlow->second << '\n';

  itup=mymap.upper_bound (25);   // itup points to 'c'
  std::cout << "upper_bound for 25:    " << itup->first << " => " << itup->second << '\n';


  return 0;
}

以下是上述代码的执行结果。

lower_bound for 20:    20 => b
upper_bound for 20:    30 => c
lower_bound for 25:    30 => c
upper_bound for 25:    30 => c

2 个答案:

答案 0 :(得分:2)

荣誉属于@rlbond。

  • 使用upper_bound然后将迭代器减1;

  • 如果从upper_bound返回的迭代器指向map.begin(),则表示地图中没有小于参数的元素。

再次感谢

#include <iostream>
#include <map>

int main ()
{
  std::map<int,char> mymap;

  mymap[10]='a';
  mymap[20]='b';
  mymap[30]='c';
  mymap[40]='d';
  mymap[50]='e';

  int nValue = 25;

  std::map<int,char>::const_iterator it=mymap.upper_bound (nValue);
  if(it != mymap.begin())
  {
      it--;
      std::cout << "last element no greater than " << nValue << " is :    " << it->first << " => " << it->second << '\n';
  }
  else
  {
      std::cout << "no element is less than " << nValue << '\n';
  }

  return 0;
}

结果给出:

last element no greater than 25 is :    20 => b

说明:

如果没有找到这样的元素,将返回

map.end(),但是,指向map.end()的迭代器仍然可以递减,只要它没有指向map.begin(),然后它就会指向所需的元素。

两个测试用例:

  • 将nValue更改为60并运行代码(在这种情况下,upper_bound将返回map.end()),您将获得“50 =&gt; e”,这是正确的。
  • 注释掉5个map set语句,留下一个空映射进行测试,然后map.end()和map.begin()是相同的,upper_bound将返回map.end(),它将打印“no element”小于XX“。还是正确的。

答案 1 :(得分:1)

Guid

然后:

template<class It>
std::optional<It> last(std::pair<It,It> range){
  if (range.first==range.second) return {};
  return std::prev(range.second);
}
template<class It>
std::optional<It> last(It b, It e){
  return last(std::make_pair(std::move(b),std::move(e)));
}
template<class C>
auto last(C& c){
  using std::begin; using std::end;
  return last(begin(c), end(c));
}