Lukas Salich
Lukas Salich

Reputation: 1000

Iterating through a set

I have a set of ints set something; of length 52. I am using cycles to iterate through the set like this:

for(iterator A from 1st to 48th element)
 for(iterator B from A+1 to 49th element)
  for(iterator C from B+1 to 50th element)
   for(iterator D from C+1 to 51th element)
    for(iterator E from D+1 to 52th element)
    {
       //save the values from the actual positions in set in array[5]
    }

First I tried to make it with an iterator but then I realised that it's not possible to start an iterator from the position of another iterator +1. Then I tried to use pointers and jump through the values but I correctly assigned only the first value and then I can't jump on second etc.

My code was:

set<int> tableAll;
for(int i=4; i!=52; ++i) 
  tableAll.insert(i);

const int * flop1 = & * tableAll.begin();
cout << * flop1 << endl;
flop1++;
cout << * flop1 << endl;

When I cout the value of pointer flop1, I get 4 and that's ok, but when I increase it and again cout on screen, I get 0, then, 49, then 0, then 1, then 0 instead 5, 6, 7, 8 and 9.

So how to iterate through my set correctly? I assume using pointers will be faster then some iterator solution.

Upvotes: 0

Views: 1867

Answers (3)

rtlgrmpf
rtlgrmpf

Reputation: 431

I'd suggest to copy the set to a temporary std::vector. All operations you do in the loops are natural for a vector and O(1) (except for the loops themselves of course) That's easier to read, to write, and should run a lot faster.

Upvotes: 0

ecatmur
ecatmur

Reputation: 157504

You absolutely can iterate from an offset from another iterator:

for (auto a(std::begin(mySet)), a_end(std::prev(std::end(mySet), 4));
        a != a_end; ++a)
    for (auto b(std::next(a)), b_end(std::next(a_end); b != b_end; ++b)
        ...

In C++03, you can write next and begin for compatibility:

template<typename Iterator> Iterator next(Iterator it, int n = 1) {
    std::advance(it, n);
    return it;
}

template<typename Iterator> Iterator prev(Iterator it, int n = 1) {
    std::advance(it, -n);
    return it;
}

for (std::set<int>::const_iterator a(mySet.begin()),
        a_end(std::prev(mySet.end(), 4)); a != a_end; ++a)
    for (std::set<int>::const_iterator b(std::next(a)),
            b_end(std::next(a_end)); b != b_end; ++b)
        ...

Upvotes: 4

Arpegius
Arpegius

Reputation: 5887

This code is not optimal as it do unneeded iterator comparisions, but works and is simply:

set<int> tableAll;
for(int i=0; i!=52; ++i)
  tableAll.insert(i);

for( set<int>::iterator iA=tableAll.begin(); iA != tableAll.end(); ++iA  )
    for( set<int>::iterator iB=iA; ++iB != tableAll.end();  )
        for( set<int>::iterator iC=iB; ++iC != tableAll.end();  )
            for( set<int>::iterator iD=iC; ++iD != tableAll.end();  )
                for( set<int>::iterator iE=iD; ++iE != tableAll.end();  ) 
{
   cout<<*iA<<' '<<*iB<<' '<<*iC<<' '<<*iD<<' '<<*iE<<endl;
}

Upvotes: 1

Related Questions