Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42929

How to flip/reverse a 2D array's rows or columns using STL

I have a 2D array of arbitrary type, of dimensions N x M (i.e., T array[N][M];) e.g.,

that I want flip it either its columns e.g.,

or its rows e.g.,

How can I do this easily just using STL?

Upvotes: 4

Views: 11353

Answers (3)

kalpana
kalpana

Reputation: 1

In 2d vector

to rotate rows we use -> reverse(a[i].begin,a[i].end());

to rotate columns we use -> reverse(a.begin(),a.end());

Upvotes: -1

Lorah Attkins
Lorah Attkins

Reputation: 5856

There's no need to move stuff in memory. A typical approach would define a traversal policy that 'travels' the array in the specified order (reversed columns or reversed rows) which is particularly efficient for really large objects that we don't want to mess with.

Showcasing this, the helper below "reverses" both rows and columns at the same time :

template<typename T, std::size_t N, std::size_t K>
struct Rev
{
    T(&data)[N][K];
    Rev(T(&data)[N][K]) : val(val) { }
    T& access(std::size_t row, std::size_t column) {
        return val[N - row - 1][K - column - 1];
    }
};

example :

int ar[2][5] = { { 1, 2, 3, 4, 5 }, { 11, 22, 33, 44, 55 } };

Rev<int, 2, 5> ob(ar);
std::cout << ob.access(1, 3); // prints 2

I opted for an access method since customizing operator[] would require returning an indexable temporary object and that takes a few more lines to be as efficient as the reference wrapper shown here; anyhow its doable in a way that matches the interface of a built in array, ie :

Rev<int, 2, 5> ob(ar)
ob[1][3]; 

In the same spirit, reverse iterators could be used to loop through slices of the array (rows or columns)

Upvotes: 2

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42929

You could do this just by using std::reverse.

Below I'm defining two generic functions namely flip_columns and flip_rows that take as input a 2D array of arbitrary type and they flip/reverse its columns and rows respectively.

Flip/Reverse 2D Array Columns

template<typename T, std::size_t N, std::size_t M>
void flip_columns(T (&arr)[N][M]) {
  std::for_each(std::begin(arr), std::end(arr),
                [](auto &i) {std::reverse(std::begin(i), std::end(i));});
}

Flip/Reverse 2D Array Rows

template<typename T, std::size_t N, std::size_t M>
void flip_rows(T (&arr)[N][M]) {
  std::reverse(std::begin(arr), std::end(arr));
}

LIVE DEMO

Upvotes: 5

Related Questions