返回最大的密钥严格小于C ++ Map中给定的密钥

时间:2009-02-09 20:39:49

标签: c++ stl

C ++ STL Maps是否支持这种方式,因为map上的lower_bound和upper_bound严格返回大于传递值的值。

Lower key

用例我有一个带有时间的地图作为按键排序,因此在MAP

time t1   = value1
time t2   = value2
time t2.5 = value3

在这种情况下,如果我传递给这个MAP t2.3,那么它应该给我value2。在地图上做一个lower_bound并返回一个等同于“返回最大密钥严格小于给定密钥”的元素,即

iterator = map.upper_bound(2.3)
and then 
iterator--;

5 个答案:

答案 0 :(得分:19)

是的,lower_bound可以用于那个,我以前见过它并像那样使用它。

map_type::iterator it = map.lower_bound(2.3);
if(it != map.begin()) {
    --it;
    // it now points at the right element
}

实际上会返回最大但更小的(如果它!= map.begin()为真)。如果是.begin,则没有小键。如果没有更少的元素并将这些内容打包到函数中,评论中的好主意就是返回.end

template<typename Map> typename Map::const_iterator 
greatest_less(Map const& m, typename Map::key_type const& k) {
    typename Map::const_iterator it = m.lower_bound(k);
    if(it != m.begin()) {
        return --it;
    }
    return m.end();
}

template<typename Map> typename Map::iterator 
greatest_less(Map & m, typename Map::key_type const& k) {
    typename Map::iterator it = m.lower_bound(k);
    if(it != m.begin()) {
        return --it;
    }
    return m.end();
}

该模板也适用于std::set

答案 1 :(得分:5)

如果您不关心排序,可以使用map :: upper_bound来获取所需的元素,但是您需要为traits参数定义带有std :: greater的map类,以便排序为高到低的。

typedef std::map<double,MyClass,std::greater<double> > MyMap;
MyMap myMap;
myMap[1.5] = value1;
myMap[2.0] = value2;
myMap[3.0] = value3;

MyMap::iterator elt = myMap.upper_bound(2.5); // should be pair(2.0,value2)

答案 2 :(得分:3)

您的方法可行,但您需要检查以确保不会回到地图的开头。另外,您需要lower_bound,而不是upper_bound。

iterator = map.lower_bound(2.3)
if (iterator != map.begin())
    --iterator;

答案 3 :(得分:2)

我会使用std :: find_if()和反向迭代器,类似于:

find_if( map.rbegin(), map.rend(), is_less_than );

您必须定义is_less_than()谓词函数。

(参见http://www.cplusplus.com/reference/algorithm/find_if.html

答案 4 :(得分:0)

我总是发现计算floor(x)和ceil(x)是有用心的

floor(x) -> greatest element <=x 
ceil(x) -> smallest element >= x

floor_it = m.lower_bound(x); 
if (floor_it != m.end() && floor_it->first != x)
      --floor_it;

ceil_it = m.upper_bound(x);
if (ceil_it != m.end() && (ceil_it-1)->first == x)
    --ceil_it;