1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
|
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <valarray>
using namespace std;
valarray<size_t> order( int start, int isize, int istride, int jsize, int jstride ) // Return order of elements
{ // for corresponding 1-d array
int n = 0;
valarray<size_t> elements( isize * jsize );
for ( int i = 0; i < isize; i++ )
{
for ( int j = 0; j < jsize; j++ ) elements[n++] = start + i * istride + j * jstride;
}
return elements;
}
template <typename T> valarray<T> rotation( const valarray<T> &V, int cols, int quarterTurns )
{
int rows = V.size() / cols;
int q = ( 4 * abs( quarterTurns ) + quarterTurns ) % 4; // Ensure correct modulo even if negative
switch( q )
{
case 0: return V;
case 1: return V[order(( rows-1)*cols, cols, 1, rows, -cols)];
case 2: return V[order( rows*cols-1 , rows, -cols, cols, -1)];
case 3: return V[order( cols-1 , cols, -1, rows, cols)];
}
}
template <typename T> void print( const valarray<T> &V, int cols )
{
for ( int n = 0; n < V.size(); n++ ) cout << setw( 3 ) << V[n] << ( ( n + 1 ) % cols ? ' ' : '\n' );
}
int main()
{
using MATRIX_TYPE = int;
// ifstream in( "matrix.dat" );
stringstream in( "3 4 \n"
"1 2 3 4 \n"
"5 6 7 8 \n"
"9 10 11 12 \n" );
int rows, cols;
in >> rows >> cols;
valarray<MATRIX_TYPE> V(rows*cols);
for ( int n = 0; n < rows * cols; n++ ) in >> V[n];
for ( int q = -4; q <= 4; q++ )
{
int width = cols; if ( q % 2 ) width = rows;
cout << "\nRotation " << q << '\n';
print( rotation( V, cols, q ), width );
}
}
|