2011-03-01 65 views
0

我有一个对象的地图,由日期键入(存储为双精度)。我想根据日期过滤/提取对象,所以我写了一个类似于下面代码片段的函数。使用lower_bound()和upper_bound()来选择记录

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

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

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

+1

“代码失败”是什么意思?如果'startdt <= recs.begin() - > first',那么'recs.lower_bound(startdt)'应该给你'recs.begin()'。 – 2011-03-01 02:42:45

回答

9

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

如果你要同时使用,无论如何,你应该使用std::equal_range代替 - 它返回迭代器的std::pair,一个是相同的lower_bound将返回,另一样upper_bound将返回。虽然它具有与分别调用两者相同的最坏情况下的复杂度,但它通常比两个单独的调用更快。

值得一提的,但是,如果你有什么是真的map(而不是multimap)只能有一个条目与给定的关键,所以没有太多的理由来应对任何给定两个lower_boundupper_bound键。

0

从GNU libstdc++

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

给定的密钥相匹配。如果 不成功它返回一个迭代 指向具有 的第一要素不是给定键或 结束(),如果没有这样的元素存在

你原来的做法上使用lower_bound更大的价值听起来正确的给我。不过,我认为你不需要使用upper_bound,你可以用enddt做一个简单的比较。我会尝试

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

    if(*cit > enddt) { 
     break; 
    } 

    // do stuff with *cit 
}