顺时针旋转 M*N 矩阵 90 度,C++
Rotate M*N matrix 90 Degrees Clockwise ,C++
我正在尝试旋转字符向量的向量。
我做了一个 2D 矢量矩阵设置。 现在矩阵从文件中获取输入, 我使用vector.push_back(c)
将字符添加到 vvc; vvc 数组的一个例子是这样的
aaaaa
azzza
azaza
azzza
azaaa
azaaa
azaaa
aaaaa
我有 vvc 设置,但我正在尝试将其旋转 90 度。我逆时针旋转了 90 度,但我需要顺时针旋转 90 度。
截至目前,我的代码这样做
90 counter clock
aaaaaaaa
azzzzzza
azazaaaa
azzzaaaa
aaaaaaaa
它通过这个循环来做到这一点;
cout <<"n90 counter clock"<<endl;
for (size_t colNo = 0; colNo < kvsize2; colNo++)
{
for (const auto &row : twovector)
{
char colVal = row.at(colNo);
cout << colVal;
}
cout << endl;
}
我只是在学习向量和范围。尝试做一个递减循环几乎有效,但总是让我陷入段错误。
"已解决">我正在使用
twovector.push_back(temp);
用
twovector.insert(twovector.begin(),temp);
给我
90 counter clock
aaaaaaaa
azzzzzza
aaaazaza
aaaazzza
aaaaaaaa
处理问题的特定部分:
如果有人对如何旋转 M*N 2d 矢量数组有任何提示或建议
C++擅长将算法与数据隔离。
请注意,答案有点长,并且是为了教程的目的而编写的。
让我们开始吧!!
我们希望从我们的rotate_2d_matrix_clockwise
算法中获得 3 个功能:
- 它应该适用于所有数据类型,即
int
、char
、double
或任何用户定义的类型。 - 它应该适用于不同类型的容器,例如
std::array
和std::vector
- 它应该是可链的,即用户应该能够调用
rotate_2d_matrix_clockwise
rotate_2d_matrix_clockwise
返回的结果,以实现2次旋转。
一旦我们明确了我们的要求,我们就可以为我们的算法起草一些用例。
std::vector<std::vector<char>> data = { {'a', 'b', 'c', 'd'},
{'e', 'f', 'g', 'h'},
{'i', 'j', 'k', 'l'} };
rotate_2d_matrix_clockwise(data); // rotating 2d-matrix of vector<char>
std::array<std::array<int, 4>, 3> data2 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
// rotating 2d-matrix of array<int>, twice
rotate_2d_matrix_clockwise(rotate_2d_matrix_clockwise(data2)));
因此,让我们使用一些模板来创建通用的 2D 顺时针旋转函数。
我们的rotate_2d_matrix_clockwise
将:
- 拿
original_matrix
并返回一个新的rotated_matrix
。 - 自动推断尺寸,即传递给它的容器的M x N。
- 创建
rotated_matrix
并将其传递给帮助程序函数,rotate_2d_matrix_clockwise_impl
实际工作将在其中完成。
那么std::array
rotate_2d_matrix_clockwise
的实施会是什么样子呢?
template<typename T, size_t M, size_t N>
auto rotate_2d_matrix_clockwise(std::array<std::array<T, M>, N> const & original_matrix)
-> std::array<std::array<T, N>, M>
{
std::array<std::array<T, N>, M> rotated_matrix;
rotate_2d_matrix_clockwise_impl(original_matrix, rotated_matrix, M, N); // rotate
return rotated_matrix;
}
整洁而精确。
不过,std::vector
的rotate_2d_matrix_clockwise
实现有点混乱。
template<typename Matrix2D>
auto rotate_2d_matrix_clockwise(Matrix2D const & original_matrix) -> Matrix2D
{
int const M = original_matrix[0].size(); // deduce M and N
int const N = original_matrix.size();
Matrix2D rotated_matrix; // vector has no form, hence we have to resize it for `N x M`
rotated_matrix.resize(M);
for (auto x = 0; x < M; ++x) {
rotated_matrix[x].resize(N);
}
rotate_2d_matrix_clockwise_impl(original_matrix, rotated_matrix, M, N); // rotate
return rotated_matrix;
}
现在让我们看看实际的旋转算法rotate_2d_matrix_clockwise_impl
会是什么样子。
应该注意的是,该算法独立于容器和/或包含的数据。它只专注于旋转。
template<typename OriginalMatrix2D, typename RotatedMatrix2D>
void rotate_2d_matrix_clockwise_impl(OriginalMatrix2D const & original_matrix,
RotatedMatrix2D & rotated_matrix,
int const M,
int const N)
{
for (auto x = 0; x < N; ++x) {
for (auto y = 0; y < M; ++y) {
// Source : https://stackoverflow.com/questions/4780119/2d-euclidean-vector-rotations
rotated_matrix[y][-x -1 +N] = original_matrix[x][y];
}
}
}
这是在 C++11 中编译的完整工作示例。
#include <iostream>
#include <vector>
#include <array>
template<typename Matrix2D>
void print_matrix(Matrix2D const & vec)
{
std::cout << "size of matrix is [" << vec[0].size() << " x " << vec.size() << "]n";
for (auto const & inner_vec : vec) {
for (auto const & item : inner_vec) {
std::cout << item << ", ";
}
std::cout << std::endl;
}
}
template<typename OriginalMatrix2D, typename RotatedMatrix2D>
void rotate_2d_matrix_clockwise_impl(OriginalMatrix2D const & matrix,
RotatedMatrix2D & rotated_matrix,
int const M,
int const N)
{
for (auto x = 0; x < N; ++x) {
for (auto y = 0; y < M; ++y) {
// Source : https://stackoverflow.com/questions/4780119/2d-euclidean-vector-rotations
rotated_matrix[y][-x -1 +N] = matrix[x][y];
}
}
}
template<typename T, size_t M, size_t N>
auto rotate_2d_matrix_clockwise(std::array<std::array<T, M>, N> const & original_matrix)
-> std::array<std::array<T, N>, M>
{
std::array<std::array<T, N>, M> rotated_matrix;
rotate_2d_matrix_clockwise_impl(original_matrix, rotated_matrix, M, N);
return rotated_matrix;
}
template<typename Matrix2D>
auto rotate_2d_matrix_clockwise(Matrix2D const & original_matrix) -> Matrix2D
{
int const M = original_matrix[0].size();
int const N = original_matrix.size();
Matrix2D rotated_matrix;
rotated_matrix.resize(M);
for (auto x = 0; x < M; ++x) {
rotated_matrix[x].resize(N);
}
rotate_2d_matrix_clockwise_impl(original_matrix, rotated_matrix, M, N);
return rotated_matrix;
}
int main()
{
std::array<std::array<int, 4>, 3> data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
std::cout << "nBefore Rotation :n";
print_matrix(data);
std::cout << "nAfter 2nd Clockwise Rotation :n";
print_matrix(rotate_2d_matrix_clockwise(rotate_2d_matrix_clockwise(data)));
std::vector<std::vector<char>> data2 = { {'a', 'b', 'c', 'd'}, {'e', 'f', 'g', 'h'}, {'i', 'j', 'k', 'l'}};
std::cout << "Before Rotation :n";
print_matrix(data2);
std::cout << "nAfter Clockwise Rotation :n";
print_matrix(rotate_2d_matrix_clockwise(data2));
return 0;
}
如果我做对了,你想要的只是顺时针打印矩阵 90 度,试试这个代码:
for (int colNo = 0; colNo < vec[0].size(); colNo++)
{
for (int i = vec.size() - 1; i >= 0; i--)
{
const auto& row = vec[i];
int colVal = row.at(colNo);
cout << colVal;
}
cout << endl;
}
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 使用std::vector的OpenCL矩阵乘法
- 使用C++中的模板和运算符重载执行矩阵运算
- Eigen如何在容器循环中干净地附加矩阵
- 当在带有Eigen的C++中使用GDB时,我如何才能看到更多的大矩阵
- 具有N列和N行的矩阵,列必须具有N-1、N-2等值
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- GCC本机矩阵运算库
- 矩阵向量乘法(cublasDgemv)返回零
- 以螺旋方式打印矩阵的程序.(工作不好)
- OpenCV C++.快速计算混淆矩阵
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 旋转模型矩阵时的形状失真
- 讨论 - 创建矩阵时的数组与向量的向量 - 什么是最实用的选择
- 如何在cuSparse中得到稀疏矩阵的对角线
- 将特征矩阵的向量设置为0
- 从C++中的数字输入动态创建矩阵
- 特征:模板函数中矩阵的平面图
- 通过常量引用传递参数的矩阵模板类