Home > Back-end >  Iterating over an std::vector two elements at a time plus last and first elements too
Iterating over an std::vector two elements at a time plus last and first elements too

Time:10-03

I am trying to iterate over a vector say {1,3,4,2} and collecting pairs basically (1,3), (3,4), (4,2), (2,1). Collecting the first three pairs is easy but doing the last one is a bit difficult.

This is what I have:

#include <vector>
#include <iostream>

int main()
{
    auto v = std::vector<int>{1,3,4,2};
    auto vecOfPairs = std::vector<std::pair<int,int>>{};

    for ( auto it = v.begin(); it != v.end() - 1;   it)
    {
        auto a = *it;
        auto b = *(it 1);
        // DO some stuff with a and b
        vecOfPairs.push_back(std::make_pair(a, b));
    }

    auto front = v.front(); 
    auto back = v.back();
    // Do the same some stuff with front and back
    vecOfPairs.push_back(std::make_pair(back, front));

    for (const auto& pair : vecOfPairs)
        std::cout << pair.first << ", " << pair.second << '\n';

}

While this works, there is some code duplication (once I have the two values, I do some further calculations with those two values before making a pair and pushing it to the vectors. Is there a way to avoid this and just do the last operating in the same for loop?

CodePudding user response:

It is simpler if you use plain subscripting. You can then add 1 and take the remainder with % v.size():

for(size_t i = 0; i < v.size();   i) {
    vecOfPairs.emplace_back(v[i], v[(i   1) % v.size()]);
}

CodePudding user response:

If you don't want a raw for-loop as in Ted's answer (and there are good reasons to avoid raw for-loops), you can do something like:

for ( auto it = v.begin(); it != v.end();   it)
{
    auto it2 = it   1;
    if (it2 == v.end()) 
    {
        it2 = v.begin();
    }

    vecOfPairs.emplace_back(*it, *it2);
}
  •  Tags:  
  • c
  • Related