使用lower_bound()和upper_bound()选择记录

时间:2011-03-01 02:40:41

标签: c++

我有一个对象地图,以日期键入(存储为双精度)。我想根据日期过滤/提取对象,所以我编写了一个类似于下面代码片段的函数。

但是,我发现如果我提供的日期低于最早日期或大于最后日期,则代码将失败。我修改了代码,以便任何低于第一个日期的输入startdate设置为地图中的第一个(即最低)日期,同样,enddate>最后日期设置为地图中的最后(最长)日期

void extractDataRecords(const DatedRecordset& recs, OutStruct& out, const double startdt, const double enddt)
{
    double first = recs.begin()->first, last = recs.rbegin()->first;
    const double sdate = (start < first) ? first : startdt;
    const double edate = (enddt > last) ? last : enddt;

    DatedRecordsetConstIter start_iter = recs.lower_bound(sdate), end_iter = recs.upper_bound(edate);

    if ((start_iter != recs.end()) && (end_iter != recs.end()))
    {

        // do Something
    }
}

这是实现此行为的正确方法吗?

2 个答案:

答案 0 :(得分:9)

std::lower_bound返回:“可以插入value而不违反排序的第一个位置。” std::upper_bound返回:“value可插入的最远位置,而不会违反排序。”换句话说,如果您在任一位置插入新项目,则可以保证集合的整体排序保持不变。

如果您打算同时使用两者,则应该使用std::equal_range代替它 - 它返回std::pair个迭代器,其中一个与lower_bound返回的迭代器相同,而另一个与upper_bound相同的将返回。虽然它具有与分别调用两者相同的最坏情况复杂性,但它通常比两次单独调用更快。

值得注意的是,如果你拥有的只是map(而不是multimap),那么只能有一个具有给定密钥的条目,所以没有太多理由要处理对于任何给定的密钥,lower_boundupper_bound都可以。

答案 1 :(得分:0)

来自GNU libstdc++

lower_bound:
This function returns the first element of a subsequence of elements
     

匹配给定的密钥。如果   不成功,它返回一个迭代器   指向第一个元素   比给定的键或更大的值   end()如果不存在这样的元素

使用lower_bound的原始方法听起来对我来说是正确的。但是,我认为您不需要使用upper_bound,您可以与enddt进行简单比较。我会试试

for( DatadRecordsetConstIter cit = recs.lower_bound( startdt ); 
        cit != rec.end(); ++cit ) {

    if( *cit > enddt ) {
        break;
    }

    // do stuff with *cit
}