Home:ALL Converter>Using std::find() With Reverse Iterators

Using std::find() With Reverse Iterators

Ask Time:2017-03-07T10:13:05         Author:Ethan

Json Formatter

I'm having some trouble understanding how to use reverse iterators with the std::find() function. I believe that if I could see an example that completed the following task, I would be able to understand it perfectly.

So, suppose I have a std::vector I want to search through; however, I do not want to search the typical way. I want to find the first occurrence of a value starting at a certain index and heading towards the start of the vector. To illustrate:


    3 | 4 | 7| 4| 2| 6| 3|
    ^             ^
    |<------------| 
             start_point

Search: find first occurrence, given the above search layout, of 4

Expected Result: index 3

I'm rather sure that one would have to work with reverse iterators in this situation, but I can't figure out how to do it.

Author:Ethan,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/42638952/using-stdfind-with-reverse-iterators
Daniel Eisener :

If you're using a std::vector, or any other container that provides Random Access Iterators, you can advance an iterator just using arithmetic, like you would with a pointer. Your example vector has 7 elements, and you want to start at index 4, so you could get a normal iterator to that element just with:\nauto i = v.begin() + 4;\n\nFor a reverse iterator, you're starting from the back of the vector, not the front, so to get the right offset you have to subtract the desired index+1 from the size, like so:\nauto i = v.rbegin() + (v.size() - 5);\n\nThis'll be, in your example, 2, so the reverse iterator will start pointing to the last element, then move two spaces toward the beginning, reaching your desired start point.\nThen, you can use std::find in the normal way:\nauto found = std::find(v.rbegin() + (v.size() - 5), v.rend(), 4);\nif(found == v.rend()) {\n std::cout << "No element found." << std::endl;\n} else {\n std::cout << "Index " << (v.rend() - found) << std::endl;\n}\n\nRemember that, when testing the result of std::find to see if it found anything, you need to use rend(), not end(). When you compare reverse iterators to normal iterators, you're comparing the actual positions, not the offsets from the start, so v.rend() != v.end().\nIf you don't have Random Access Iterators (for example, in a std::list) you can't use pointer-style arithmetic, so you can instead use std::advance to advance iterators to a specific position and std::distance to get the distance between two iterators.",
2017-03-07T02:25:35
Kerrek SB :

First you set the start position:\n\nauto it = v.rbegin() + 2; // two from the end\n\n\nThen search:\n\nauto kt = std::find(it, v.rend(), 4);\n\n\nIf kt == v.rend(), no element is found; otherwise we can compute the index from the front with a simple distance computation:\n\nif (kt == v.rend()) {\n std::cerr << \"Element 4 not found.\\n\";\n std::abort();\n} else {\n auto n = std::distance(kt, v.rend()) - 1;\n std::cout << \"Element 4 found at position v[\" << n << \"].\\n\";\n}\n",
2017-03-07T02:17:00
yy