17

我知道如何从向量迭代器中获取索引,方法是从中减去开始迭代器。例如:

vector<int>::iterator it = find(vec.begin(), vec.end(), x);
size_t position = it - vec.begin();

但是,现在我想找到x向量中最后一个的索引。如何从反向迭代器中获取真实索引?我发现以下似乎有效(编辑:它没有)但也许有更好的(更惯用的或其他......)方式。

vector<int>::reverse_iterator it = find(vec.rbegin(), vec.rend(), x);
size_t position = vec.size() - (it - vec.rbegin());
4

3 回答 3

17

我会使用:

#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
    auto v = std::vector<int> { 1, 2, 3 };
    auto rit = std::find(v.rbegin(), v.rend(), 3);
    if (rit != v.rend()) {
        auto idx = std::distance(begin(v), rit.base()) - 1;
        std::cout << idx;
    } else
        std::cout << "not found!";
}

活生生的例子

-1距离计算的原因是由于.base()成员中反向迭代器和常规迭代器之间的转换:

24.5.1 反向迭代器 [reverse.iterators]

1 类模板 reverse_iterator 是一个迭代器适配器,它从其底层迭代器定义的序列的末尾迭代到该序列的开头。反向迭代器与其对应的迭代器 i 之间的基本关系由恒等式建立:&*(reverse_iterator(i)) == &*(i - 1)

注意:您也可以使用上面的代码而不检查v.rend(),并使用idx == -1等效于未找到元素的约定。但是,这失去了做的能力v[idx],所以最终你也需要检查一下。

于 2014-07-28T14:55:38.687 回答
5

你可以使用:

container.size() - 1 - (iterator - container.rbegin())

或者

container.size() - 1 - std::distance(container.rbegin(), iterator)

有关反向迭代器的更多信息。如何在不混淆的情况下使用反向迭代器。将反向迭代器转换为正向迭代器等等。

于 2014-07-28T14:55:08.857 回答
4

我会将 TemplateRex 的答案更改为仅使用反向迭代器,从而避免因反向正向转换而感到头疼。

int main()
{
    auto v = std::vector<int> { 1, 2, 3 };
    auto rit = std::find(v.rbegin(), v.rend(), 3);
    if (rit != v.rend()) {
        auto idx = std::distance(rit, v.rend()) - 1;
        std::cout << idx;
    } else
        std::cout << "not found!";
}

-1仍然需要,因为向量的第一个元素(索引 0)实际上在v.rend() - 1.

于 2020-11-17T20:50:32.380 回答