Обратите внимание, что транспонирование матрицы на месте не является тривиальным, когда N!=M
.См. Например здесь для получения подробной информации.
Причина в том, что когда N=M
, вы можете просто перебрать половину матрицы и поменять местами элементы.Когда N!=M
это не так.
Для иллюстрации рассмотрим более простой случай:
Сначала 2-мерное представление для 1d данных:
struct my2dview {
std::vector<int>& data;
int width,height;
my2dview(std::vector<int>& data,int width,int height):data(data),width(width),height(height){}
int operator()(int x,int y) const { return data[x*width + y]; }
int& operator()(int x,int y){ return data[x*width + y]; }
my2dview get_transposed() { return my2dview(data,height,width);}
};
std::ostream& operator<<(std::ostream& out, const my2dview& x){
for (int h=0;h<x.height;++h){
for (int w=0;w<x.width;++w){
out << x(h,w) << " ";
}
out << "\n";
}
return out;
}
Теперь транспонирование, которое будет работать для N=M
:
my2dview broken_transpose(my2dview x){
auto res = x.get_transposed();
for (int i=0;i<x.height;++i){
for (int j=0;j<x.width;++j){
res(j,i) = x(i,j);
}
}
return res;
}
Использование его для некоторой небольшой матрицы
int main() {
std::vector<int> x{1,2,3,4,5,6};
auto v = my2dview(x,2,3);
std::cout << v << '\n';
std::cout << v.get_transposed() << '\n';
auto v2 = broken_transpose(v);
std::cout << v2;
}
printints
1 2
3 4
5 6
1 2 3
4 5 6
1 3 2
2 2 6
Вывод: подход наивных элементов обмена не работает для неквадратных матриц.
На самом деле этот ответ перефразирует ответ @Alan Birtles.Я чувствовал, что его
испытывает трудности из-за сложности задачи, на самом деле может оказаться быстрее создать временный буфер [...]
, просто чтобы прийтик такому же выводу;).