Reputation: 42929
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
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
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
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.
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));});
}
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));
}
Upvotes: 5