我在这里看到几个问题并没有完全回答我的问题。我正在尝试对面试问题中经常使用的经典矩阵旋转问题进行演绎。我没有关注方阵,而是对 M x N 矩阵感兴趣。
对于输入矩阵
1 2 3
4 5 6
7 8 9
1 2 3
我想将矩阵转换成
3 2 1
9 8 7
6 5 4
3 2 1
这是我写的代码:
#include <iostream>
#include <vector>
#include <algorithm>
void do_swaps(int& a, int& b, int& c, int& d) {
std::swap(a, b);
std::swap(c, d);
}
void rotate(std::vector<std::vector<int>>& v) {
size_t m = v.size();
size_t n = v[0].size();
for(size_t i = 0; i < m/2; ++i) {
for(size_t j = 0; j <= n/2; ++j) {
do_swaps(v[i][j], v[m-i-1][n-j-1], v[m-j-1][i], v[j][n-i-1]);
}
}
}
void print(const std::vector<std::vector<int>>& v) {
size_t m = v.size();
size_t n = v[0].size();
for(size_t i = 0; i < m; ++i) {
for(size_t j = 0; j < n; ++j) {
std::cout << v[i][j] << ' ';
}
std::cout << '\n';
}
}
int main() {
std::vector<std::vector<int>> m{{1,2,3}, {4,5,6}, {7,8,9}, {1, 2, 3}};
std::cout << "Before: \n";
print(m);
rotate(m);
std::cout << "\nAfter: \n";
print(m);
}
这是我的输出:
Before:
1 2 3
4 5 6
7 8 9
1 2 3
After:
3 2 1
9 5 7
6 8 4
3 2 1
我的代码适用于 3 x 3 矩阵(尚未测试更高维矩阵),但我的代码中似乎有一个错误导致最里面的元素保持未交换状态。
在行for(size_t j = 0; j <= n/2; ++j) {
,我已经尝试将停止条件调整为包括 j < (n+1)/2;
在内的几件事和 j < (n-1)/2;
, 但它保持不变。
谁能解释一下我的算法哪里出了问题?
最佳答案
如果行号为奇数,则无需处理中间行。
此外,您将位于中间列(当列数为奇数时)的元素交换两次。您可以使用按位与 1 检查 m
是否为奇数。
以下是一种更简单的投影交换值的方法,在这种情况下您甚至不必关心中间列。
void rotate(std::vector<std::vector<int>>& v) {
size_t m = v.size();
size_t n = v[0].size();
for (size_t i = 0; i < m / 2; ++i)
{
for (size_t j = 0; j < n; ++j)
std::swap(v[i][j], v[m - i - 1][n - j - 1]);
}
if (m&1)
for (size_t i = 0; i< n/2; ++i)
std::swap(v[m/2][i], v[m/2][n-i-1]);
}
关于c++ - 如何将 M x N 矩阵原地旋转 180 度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36392712/