Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get index in vector from reverse iterator

I know how to get the index from a vector iterator, by subtracting the begin iterator from it. For example:

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

However, now I want to find the index of the last x in the vector. How can I get the real index from the reverse iterators? I've found the following that seems to work (edit: it doesn't) but maybe there is a better (more idiomatic or whatever..) way.

vector<int>::reverse_iterator it = find(vec.rbegin(), vec.rend(), x);
size_t position = vec.size() - (it - vec.rbegin());
like image 814
Neil Kirk Avatar asked Jul 28 '14 14:07

Neil Kirk


People also ask

How do you iterate through a vector in reverse?

So, to iterate over a vector in reverse direction, we can use the reverse_iterator to iterate from end to start. vector provides two functions which returns a reverse_iterator i.e. vector::rend() –> Returns a reverse iterator that points to the virtual element before the start of vector.

How do you access vectors using iterators?

You need to make use of the begin and end method of the vector class, which return the iterator referring to the first and the last element respectively. using namespace std; vector<string> myvector; // a vector of stings. // push some strings in the vector. myvector. push_back("a"); myvector.

How do you find the index of a vector in C++?

How to find index of a given element in a Vector in C++. find (): Used to find the position of element in the vector. Subtract from the iterator returned from the find function, the base iterator of the vector . Finally return the index returned by the subtraction.

What is reverse iterator in C++?

class reverse_iterator; std::reverse_iterator is an iterator adaptor that reverses the direction of a given iterator. In other words, when provided with a bidirectional iterator, std::reverse_iterator produces a new iterator that moves from the end to the beginning of the sequence defined by the underlying bidirectional iterator.

How to iterate vector elements in backward direction using for loop?

To Iterate vector elements in backward direction using for loop, we can traverse vector from backward direction by running a loop from the index (vector. size ()-1) to index 0. The Vector class has ListIterator method, which is used to iterate over the vectors.

How do you know if an iterator is one past the end?

For a reverse iterator r constructed from an iterator i, the relationship &*r == &*(i-1) is always true (as long as r is dereferenceable); thus a reverse iterator constructed from a one-past-the-end iterator dereferences to the last element in a sequence.


Video Answer


2 Answers

I would use:

#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!";
}

Live Example.

The reason for the -1 in the distance computation is because of the conversion between reverse and regular iterators in the .base() member:

24.5.1 Reverse iterators [reverse.iterators]

1 Class template reverse_iterator is an iterator adaptor that iterates from the end of the sequence defined by its underlying iterator to the beginning of that sequence. The fundamental relation between a reverse iterator and its corresponding iterator i is established by the identity: &*(reverse_iterator(i)) == &*(i - 1).

Note: you could also use the above code without the check for v.rend(), and use the convention that idx == -1 is equivalent to an element that is not found. However, that loses the ability to do v[idx], so eventually you would need a check against that as well.

like image 171
TemplateRex Avatar answered Sep 18 '22 05:09

TemplateRex


You could use:

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

or

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

More info about reverse iterators. How To Use Reverse Iterators Without Getting Confused. To convert reverse iterators into forward iterators and much more.

like image 30
NetVipeC Avatar answered Sep 21 '22 05:09

NetVipeC