Home > Blockchain >  Iterating in reverse direction in c
Iterating in reverse direction in c

Time:10-22

When we are iterating in reverse direction i see that most of the people are using the following structure

for(auto it=vec.rbegin();it!=vec.rend();it  )
{
     //block of code//
}

But from long back i have a doubt about using this and i have the following questions to ask

  1. Why does the following code does not work ,as we know that the last element will be having the highest index than any element index in the array as the array is going to take contiguous memory and my primary doubt is when iterating backwards why shouldn't we use it-- AND I WANT THE REASON WHY THE FOLLOWING CODE IS NOT GOING TO WORK BECAUSE I AM RUNNING THE LOOP FROM THE RBEGIN THAT IS THE LAST ELEMENT AND AM GOING TILL THE FIRST ELEMENT AND I AM DECREMENTING THE IT BY ONE IN EVERY ITERATION.
   for(auto it=vec.rbegin();it>=arr.begin();it--)
    {
       cout<<*it<<endl;
    }

EVEN THE BELOW CODE IS NOT WORKING

    FOR(auto it=vec.rbegin();it>=arr.begin();it  )
    {
       cout<<*it<<endl;
    }

any logical and relevent answers are most welcome.

CodePudding user response:

[...] I WANT THE REASON WHY THE FOLLOWING CODE IS NOT GOING TO WORK [...]

In the given codes, the for loop's conditions are making issue due to type-mismatch.

The vec.rbegin() gives the std::vector::reverse_iterator, and the vec.begin() gives the std::vector::iterator; those are different types and can not compare their values. Hence, the compiler error -> not possible situation!


That being said, using std::reverse_iterator::base(), you could get/ convert the reverse iterator to the corresponding iterator, and it can be compared with the vec.begin().

for (auto it = vec.rbegin(); it.base() != vec.begin();   it)
//                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
   std::cout << *it << " ";
}

See a demo


Side Note:

  • Even though, the above is possible, I would strongly suggest use the same iterators for comparison, which provides the code more natural look, and easy to understand for the fellow devs and less error-prone.
  • Read more: Can I convert a reverse iterator to a forward iterator?

CodePudding user response:

Here is an example if you insist mix begin() with rbegin()

#include<iostream>
#include<vector>
using namespace std;
int main() {
    vector<int> a = {1,2,3};
    for(auto it = a.rbegin(); (std::reverse_iterator<std::__wrap_iter<int *>>)(it-1) !=(std::reverse_iterator<std::__wrap_iter<int *>>) a.begin(); it  ) {
        cout<<*it<<" ";
    }
    return 0;
}
  • Compile and run:

    g   -Wall demo.cpp -o demo.out
    ./demo.out
    
  • Output:

    3 2 1 0
    
  •  Tags:  
  • c
  • Related