C++ Rotate the given matrix the specified number of times

Rotate the given matrix the specified number of times. My code rotates only one time (90 degrees to right). How to write a loop or something that it could work properly? K-number of times<=1000001; n-matrix dimensions<=101.
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
  #include <iostream>
using namespace std;
 
int main()
{
    int n;
    cin>>n;
    int** a=new int*[n];
    for(int i=0; i<n;i++) {
        a[i]=new int[n];
    }
    int** b=new int*[n];
    for(int i=0; i<n;i++) {
        b[i]=new int[n];
    }
    for (int i=0;i<n;i++){
        for (int j=0;j<n;j++){
            cin>>a[i][j];
        }
    }
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            b[i][n-1-j] = a[j][i];
        }
    }
    //cout<<endl;
    for(int i=0;i<n;i++){
            for(int j=0;j<n;j++)
            {
                cout<<b[i][j];
                if (j != n - 1) {
                cout<<" ";}
 
            }
                cout<<endl;
    }
    return 0;
}
Brute force:

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
#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>

// vectors: https://cal-linux.com/tutorials/vectors.html
// Prefer using STL array or vector instead of a C array
// http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rsl-arrays
// our matrix is a vector of rows, where each row is a vector of some type T
template < typename T > using matrix_t = std::vector< std::vector<T> > ;

template < typename T > matrix_t<T>& transpose_square_matrix( matrix_t<T>& mtx )
{
    const std::size_t n = mtx.size() ;

    using std::swap ; // http://en.cppreference.com/w/cpp/algorithm/swap
    for( std::size_t i = 0 ; i < (n-1) ; ++i )
        for( std::size_t j = i+1 ; j < n ; ++j )
            swap( mtx[i][j], mtx[j][i] ) ;

    return mtx ;
}

template < typename T > matrix_t<T>& reverse_rows( matrix_t<T>& mtx )
{
    // http://www.stroustrup.com/C++11FAQ.html#for
    // http://www.stroustrup.com/C++11FAQ.html#auto
    // http://en.cppreference.com/w/cpp/algorithm/reverse
    for( auto& row : mtx ) std::reverse( std::begin(row), std::end(row) ) ;
    return mtx ;
}

template < typename T > matrix_t<T>& rotate_square_matrix_right( matrix_t<T>& mtx )
{ return reverse_rows( transpose_square_matrix(mtx) ) ; }

template < typename T > matrix_t<T>& rotate_square_matrix_left( matrix_t<T>& mtx )
{ return transpose_square_matrix( reverse_rows(mtx) ) ; }

template < typename T > void print( const matrix_t<T>& mtx, int width = 4 )
{
    for( const auto& row : mtx )
    {
        for( int v : row ) std::cout << std::setw(width) << v ;
        std::cout << '\n' ;
    }
    std::cout << "\n\n" ;
}

int main()
{
    const int NROTATIONS = 3 ;

    std::vector< std::vector<int> > mtx { { 10, 11, 12, 13 }, { 14, 15, 16, 17 },
                                          { 18, 19, 20, 21 }, { 22, 23, 24, 25 } } ;
    print(mtx) ;

    for( int i = 0 ; i < NROTATIONS ; ++i ) print( rotate_square_matrix_right(mtx) ) ;

    for( int i = 0 ; i < NROTATIONS ; ++i ) print( rotate_square_matrix_left(mtx) ) ;
}

http://coliru.stacked-crooked.com/a/de0e5beeffb9c13a
Thanks a lot!
By the way, may I ask something? How to input and output matrix(es) from/into a file in this case?
Last edited on
To read input from a file, open the file for input: std::ifstream file_in( "my_file.txt" ) ;
and then use file_in as you would use std::cin

To write to a file, open the file for output: std::ofstream file_out( "my_file.txt" ) ;
and then use file_out as you would use std::cout


For example:

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
63
#include <iostream>
#include <vector>
#include <cmath>
#include <iomanip>
#include <fstream>

template < typename T > using matrix_t = std::vector< std::vector<T> > ;

template < typename T > matrix_t<T> read_square_matrix( std::istream& stm )
{
    // 1. read all the values into a vector
    std::vector<T> values ;
    T v ;
    while( stm >> v ) values.push_back(v) ;

    // 2. compute the size n of the nxn matrix
    std::size_t n = std::sqrt( values.size() ) ;
    while( n*n > values.size() ) --n ; // adjust for possible floating point inaccuracies

    // 3. create the nxn matrix
    matrix_t<T> mtx ;
    for( auto iter = values.begin() ; mtx.size() < n ; iter += n ) // create n rows
        mtx.emplace_back( iter, iter+n ) ; // each containing n items

    return mtx ; // and return it
}

template < typename T > bool write_matrix( std::ostream& stm, const matrix_t<T>& mtx, int width = 4 )
{
    for( const auto& row : mtx )
    {
        for( int v : row ) stm << std::setw(width) << v ;
        stm << '\n' ;
    }

    return bool( stm << "\n\n" ) ;
}

int main()
{
    const std::vector< std::vector<int> > mtx { { 10, 11, 12, 13 }, { 14, 15, 16, 17 },
                                                { 18, 19, 20, 21 }, { 22, 23, 24, 25 } } ;

    const std::string file_name = "matrix.txt" ;

    {
        // write the matrix into a file
        std::ofstream file(file_name) ; // open the file for output
        write_matrix( file, mtx ) ; // write the matrix
    }

    // dump the contents of the file to stdout to verify that it was written correctly
    std::cout << std::ifstream(file_name).rdbuf() ;

    {
        // read the matrix back from the file
        std::ifstream file(file_name) ; // open the file for input
        const auto mtx_read_in = read_square_matrix<int>(file) ; // read the matrix of integers

        // dump the contents of mtx_read_in to stdout to verify that it was read correctly
        write_matrix( std::cout, mtx_read_in ) ;
    }
}

http://coliru.stacked-crooked.com/a/18f514c1a8c296b2
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 );
   }
}


Rotation -4
  1   2   3   4
  5   6   7   8
  9  10  11  12

Rotation -3
  9   5   1
 10   6   2
 11   7   3
 12   8   4

Rotation -2
 12  11  10   9
  8   7   6   5
  4   3   2   1

Rotation -1
  4   8  12
  3   7  11
  2   6  10
  1   5   9

Rotation 0
  1   2   3   4
  5   6   7   8
  9  10  11  12

Rotation 1
  9   5   1
 10   6   2
 11   7   3
 12   8   4

Rotation 2
 12  11  10   9
  8   7   6   5
  4   3   2   1

Rotation 3
  4   8  12
  3   7  11
  2   6  10
  1   5   9

Rotation 4
  1   2   3   4
  5   6   7   8
  9  10  11  12
Topic archived. No new replies allowed.