Home > database >  How to increment the C list's Iterator inside a for loop to iterate over specific pattern say
How to increment the C list's Iterator inside a for loop to iterate over specific pattern say

Time:10-04

Usually in C one can iterate over each second element by doing so:

for (int i = 0; i < 10; i = i   2 ){ 
       //do Somthing 
}

and for a C list (from library list) one can iterate over each element like so:

std::list<int> dY = {5,4,5,8,9,7,10,4};
std::list<int>::iterator iterdY;
for (iterdY = dY.begin(); iterdY != dY.end(); iterdY  ) {
        // do Something
    }

Now my question is what should I write instead of iterdY to iterate over each second element ??

CodePudding user response:

Probably the easiest way is to introduce a second iteration variable.

std::list<int> dY;
int n = 0;
std::list<int>::iterator iterdY = {5,4,5,8,9,7,10,4};
for (iterdY = dY.begin(); iterdY != dY.end(); iterdY  ,   n) {
    if ((n % 2) == 0) {
        // do Something
    }
}

CodePudding user response:

For starters I think you mean a list in this declaration

std::list<int>::iterator iterdY = {5,4,5,8,9,7,10,4};

like

std::list<int> dY = {5,4,5,8,9,7,10,4};

instead of the iterator.

You can do something like the following

for ( auto it = dY.begin(); it != dY.end();   it == dY.end() ? it :   it ) {
//...

Here is a demonstration program.

#include <iostream>
#include <list>

int main() 
{
    std::list<int>dY = {5,4,5,8,9,7,10,4}; 

    for ( auto it = dY.begin(); it != dY.end();   it == dY.end() ? it :   it )
    {
        std::cout << *it << ' ';
    }
    std::cout << '\n';       
}

The program output is

5 5 9 10

CodePudding user response:

std::advance(iterdY, 2)

But you can no longer use the comparison iterdY != dY.end() because if the list has an odd number of elements you will skip over the end iterator, and into the territory of undefined behavior.

You must make sure that the list have an even number of elements first, if using iterators, or use some other way to keep track of the iterator not passing beyond the end.


If your compiler supports C 23 you can use ranges and stride_view to skip over every second element in the container.

See example here (using the earlier Ranges v3 library, which is the base for the C 20 standard library ranges).

Using the original ranges v3 library with earlier C standards is possible as well.

CodePudding user response:

I'd use two steps and a function:

auto iterdY = dY.begin();
while (iterDy != dy.end()) {
    do_something(*iterDy  );
    if (iterDy == dY.end())
        break;
    do_something(*iterDy  );
}

CodePudding user response:

After understanding all of suggested answers I would like to propose this solution:

#include <iostream>
#include <string>
#include <list>
using namespace std;

int main()
{
    std::list<int> dY = {5,4,5,8,9,10,11}; 
    std::list<int>::iterator it = dY.begin();
    int step = 3; // Here one can change the step to print each third element
    for (int i = 0 ; i < dY.size() ; i = step )
    {
        std::cout << *it <<'\n';
        std::advance(it, step);
    } 
    std::cout << '\n';       
}

output is:

5 8 11

  • Related