Have a nice day
Have a nice day

Reputation: 1015

Shift matrix columns/rows in all directions c++

I have a 2d vector that looks like this:

a b c
d f g  // actual size is 32 x 32
h i j

And I want to shift the rows/columns:

d f g          h i j           b c a           c a b
h i j <-- up   a b c <-- down  f g d <-- left  g d f <-- right  
a b c          d f g           i j h           j h i     

In python I can accomplish all of those in nifty one liners, such as matrix = [row[-1:] + row[:-1] for row in matrix] to move the columns to the right. But, c++ doesn't use the handy : in list indexes or negative indexes. Well, not negative indexes like in python at least.

Anyway, I'm looking for a good way to do this. I've seen lots of other SO questions about swapping rows, or rotating, but none I have seen have solved my problem.

Here's my first take on moving columns to the right:

vector<vector<string>> matrix{{"a","b","c"}, {"d","e","f"}, {"g","h","i"}};

for (int i = 0; i < matrix.size(); i++)
{
    vector<string> col{matrix[i][2], matrix[i][0], matrix[i][1]};
    matrix[i] = col;
}

This works, but will be very long once I write all 32 indexes. I was hoping someone could point me to something shorter and more flexible. Thanks!

EDIT: For future viewers (taken from G. Sliepen's answer) :

vector<vector<string>> matrix{{"a","b","c"}, {"d","e","f"}, {"g","h","i"}}; // or can be ints

rotate(matrix.begin(), matrix.begin() + 1, matrix.end()); // move rows up
rotate(matrix.begin(), matrix.begin() + matrix.size() - 1, matrix.end()); // move rows down

for (auto &row: matrix) // move columns to the left
{
    rotate(row.begin(), row.begin() + 1, row.end());
}
for (auto &row: matrix) // move columns to the right
{
    rotate(row.begin(), row.begin() + row.size() - 1, row.end()); 
}

Upvotes: 3

Views: 927

Answers (1)

G. Sliepen
G. Sliepen

Reputation: 7984

There is std::rotate() that can do this for you. To rotate the contents of each row:

vector<vector<string>> matrix{{"a","b","c"}, {"d","e","f"}, {"g","h","i"}};

for (auto &row: matrix)
{
    std::rotate(row.begin(), row.begin() + 1, row.end());
}

To rotate the contents of the columns, you just rotate the outer vector:

std::rotate(matrix.begin(), matrix.begin() + 1, matrix.end());

Upvotes: 4

Related Questions