I was thinking the approach to finding the transpose of a matrix and below is the algorithm but it is not giving me proper output , so anyone can tell me where I have done mistake and what should be proper algorithm ? And how can I improve it ?
// m is the number of rows and n is the number of columns in a matrix
for (int i = 0; i < m; i ) // For swapping the non-diagonal elements
{
for (int j = 0; j < n; j )
{
if (i != j)
{
int temp = 0;
temp = a[i][j];
a[i][j] = a[j][i];
a[j][i] = temp;
}
}
}
cout << "Elements of transpose matrix of a is: " << endl;
for (int i = 0; i < m; i ) // printing the elements after transpose
{
for (int j = 0; j < n; j )
{
cout << a[i][j] << " ";
}
cout << endl;
CodePudding user response:
You made the same mistake one can make while reversing a 1D array, hence I will use that as a simpler example:
#include <vector>
#include <iostream>
#include <utility>
std::vector<int> reverse_broken(std::vector<int> x){
for (size_t i=0;i< x.size(); i){
std::swap(x[i],x[x.size()-1-i]);
}
return x;
}
int main(){
auto x = reverse_broken({1,2,3,4});
for (const auto& e : x) std::cout << e << " ";
}
1 2 3 4
reverse_broken
iterates all elements and swaps them with the respective reversed element. However, once the first has been swapped with the last, the last has already been swapped. Later swapping the last with the first puts them in the original order again.
Same with your transpose. Once you swapped an element above the diagonal with one below the diagonal, they are already transposed. You don't need to swap them again.
I'll show you the fix for the reverse_broken
and leave it to you to apply same fix to your transpose:
std::vector<int> reverse(std::vector<int> x){
for (size_t i=0;i< x.size()/2; i){
// stop in the middle ^^ because then all elements have been swapped
std::swap(x[i],x[x.size()-1-i]);
}
return x;
}
You should also consider to not transpose the matrix at all. Depending on how often you access swapped elements and how you populate it, it will be cheaper to either populate it in right order from the start, or just swapping the indices on access:
// normal access:
auto x = a[i][j];
// transposed access:
auto y = a[j][i];
PS: I used reverse
only for illustration. To reverse a container you should actually use std::reverse
. Also note that you can and should use std::swap
. And last but not least, only a square matrix can be transposed in place. For a non square matrix you need to construct a new one with different dimensions.