Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clean ways to write multiple 'for' loops

Tags:

c++

for-loop

For an array with multiple dimensions, we usually need to write a for loop for each of its dimensions. For example:

vector< vector< vector<int> > > A;  for (int k=0; k<A.size(); k++) {     for (int i=0; i<A[k].size(); i++)     {         for (int j=0; j<A[k][i].size(); j++)         {             do_something_on_A(A[k][i][j]);         }     } }  double B[10][8][5]; for (int k=0; k<10; k++) {     for (int i=0; i<8; i++)     {         for (int j=0; j<5; j++)         {             do_something_on_B(B[k][i][j]);         }     } } 

You see this kind of for-for-for loops in our code frequently. How do I use macros to define the for-for-for loops so that I don't need to re-write this kind of code every time? Is there a better way to do this?

like image 418
C. Wang Avatar asked Jan 08 '14 11:01

C. Wang


People also ask

Can you have multiple for loops?

The outer loop can contain more than one inner loop. There is no limitation on the chaining of loops. In the nested loop, the number of iterations will be equal to the number of iterations in the outer loop multiplied by the iterations in the inner loop.

How do you do multiple for loops in C++?

Syntax for Nested Do-While loop:do{ do{ // statement of inside loop }while(condition); // statement of outer loop }while(condition); Note: There is no rule that a loop must be nested inside its own type. In fact, there can be any type of loop nested inside any type and to any level.

Can you have multiple for loops in C++?

A loop can be nested inside of another loop. C++ allows at least 256 levels of nesting.


1 Answers

The first thing is that you don't use such a data structure. If you need a three dimensional matrix, you define one:

class Matrix3D {     int x;     int y;     int z;     std::vector<int> myData; public:     //  ...     int& operator()( int i, int j, int k )     {         return myData[ ((i * y) + j) * z + k ];     } }; 

Or if you want to index using [][][], you need an operator[] which returns a proxy.

Once you've done this, if you find that you constantly have to iterate as you've presented, you expose an iterator which will support it:

class Matrix3D {     //  as above...     typedef std::vector<int>::iterator iterator;     iterator begin() { return myData.begin(); }     iterator end()   { return myData.end();   } }; 

Then you just write:

for ( Matrix3D::iterator iter = m.begin(); iter != m.end(); ++ iter ) {     //  ... } 

(or just:

for ( auto& elem: m ) { } 

if you have C++11.)

And if you need the three indexes during such iterations, it's possible to create an iterator which exposes them:

class Matrix3D {     //  ...     class iterator : private std::vector<int>::iterator     {         Matrix3D const* owner;     public:         iterator( Matrix3D const* owner,                   std::vector<int>::iterator iter )             : std::vector<int>::iterator( iter )             , owner( owner )         {         }         using std::vector<int>::iterator::operator++;         //  and so on for all of the iterator operations...         int i() const         {             ((*this) -  owner->myData.begin()) / (owner->y * owner->z);         }         //  ...     }; }; 
like image 180
James Kanze Avatar answered Sep 19 '22 03:09

James Kanze