多重ループのループ変数を外で使う
何のことかと思うかもしれないが今仕事で必要になった(’’ 案外難しかった。
普通、ループを回したい時は以下のようになるだろう。
for( int z = 0; z < sizeZ; ++z ){ for( int y = 0; y < sizeY; ++y ){ for( int x = 0; x < sizeX; ++x ){ Funct( z, y, x ); } } }
しかしとある事情により、Functをループの中に入れるのが無理な状況がでてきて、ループ変数を随時返すような関数の実装が必要になった。具体的には以下のような状況である。
int z(0), y(0), x(0); do{ Funct( z, y, x ); }while( Loop3( z, y, x ) );
なんで後評価なんだとか言われそうだがただ単にstd::next_permutationっぽくしたかっただけ(ぇー んで、このLoop3をどう実装すれば言いかというのが問題である。
あんまり粘れないで申し訳ないが答えは以下の通り
bool Loop3( int& z, int& y, int& x ) { ++x; if( !( x < sizeX ) ){ ++y; if( !( y < sizeY ) ){ ++z; if( !( z < sizeZ ) ){ return false; } y = 0; } x = 0; } return true; }
試してみればわかるが同じ結果が返るはず。これ見つけるの、結構苦労しました(’’ まだまだですな・・。
んで、ただ単にループ変数を返すだけなら計算で出せてしまう。
bool Loop3( int& z, int& y, int& x ) { static t = 0; ++t; x = t % sizeX; y = ( t / sizeX ) % sizeY; z = ( ( t / sizeX ) / sizeY ) % sizeZ; return true; }
しかしこれ、ループ条件がその前のループ変数に依存する場合、激烈に難しくなる・・・ていうか無理。
for( int z = minZ; z < maxZ; ++z ){ for( int y = minY( z ); y < max( z ); ++y ){ for( int x = minX( z,y ); x < maxX( z,y ); ++x ){ Funct( z, y, x ); } } }
だけれども、最初の方法だったらあんまり変更なく出来ちゃいます。
bool Loop3( int& z, int& y, int& x ) { ++x; if( !( x < maxX(z,y) ) ){ ++y; if( !( y < maxY(z) ) ){ ++z; if( !( z < maxZ ) ){ return false; } y = minY(z); } x = minX(z,y); } return true; } int z(minZ), y(minY(z)), x(minX(z,y)); do{ Funct( z, y, x ); }while( Loop3( z, y, x ) );
というわけで漸く仕事が進みそうです。疲れたorz