std :: vector上的std :: lower_bound与反向迭代器产生错误的结果

时间:2014-06-15 10:31:02

标签: c++ vector stl

最近我发现需要计算超出给定间隔的元素。

例如,如果我有一个有序矢量{10,20,30}和另一个有序矢量{15,25},其边界定义了间隔。我想数'10'和'30'(只有20在范围内)。为此,我使用std :: vector和std :: lower_bound,一次向前扫描向量,一次向后扫描。

代码如下:

    int t[] = { 15, 25 };
int c[] = { 10, 20, 30 };

std::vector<int> tt(t, t + 2);
std::vector<int> cc(c, c + 3);

auto lower = std::lower_bound(cc.begin(), cc.end(), tt.front(), [](int a, int b){ return a < b; });
auto upper = std::lower_bound(cc.rbegin(), cc.rend(), tt.back(), [](int a, int b){ return a > b; });

size_t beforeCount = lower - cc.begin();
size_t afterCount = upper - cc.rbegin();

我希望'lower'和'upper'指向相同的元素:20。

我花了一些时间在这上面,有没有人在这看到问题? 我真的很想使用STL。

谢谢你, 亚历

2 个答案:

答案 0 :(得分:2)

我认为你在迭代器的差异和迭代器指向的值之间感到困惑。

您的计划完全符合您的想法,请参阅here

beforeCountafterCount都等于1.它们是迭代器,而不是任何向量元素的值,它们只是指向向量中值的指针。

要打印相应的元素,只需执行以下操作:

std::cout << cc[beforeCount] << std::endl;
std::cout << cc[afterCount] << std::endl;

<强>输出:

20

20

注意:

您可以在没有中间数组的情况下初始化矢量:

std::vector<int> tt { 15, 25 };
std::vector<int> cc  { 10, 20, 30 } ;

答案 1 :(得分:0)

我发现有时很难推断反向迭代器。您可以避免使用它们如下:

auto first = std::lower_bound(cc.begin(), cc.end(), tt.front());
auto second = std::upper_bound(first, cc.end(), tt.back());

size_t beforeCount = first - cc.begin();
size_t afterCount = cc.end() - second;

这与equal_range非常相似,所以实际上我们可以按如下方式重写它(尽管在过去使用非标准实现w.r.t.异构比较器的MSVC上可能会很麻烦):

typedef std::pair<int, int> Pr;
struct Cmp {
    bool operator()(int x, const Pr &y) { return x < y.first; }
    bool operator()(const Pr &x, int y) { return x.second < y; }
};
auto pr = std::equal_range(cc.begin(), cc.end(), Pr(15, 25), Cmp());

size_t beforeCount = pr.first - cc.begin();
size_t afterCount = cc.end() - pr.second;