ちょっと気になったので考えてみました。こんなのはどうでしょう。
行列クラスを作って、カスタマイズして転置の処理を加えました。
コード:
class IntMatrix2D
{
private:
int* entity; // 要素を用意するためだけに必要
int** elements; // 行列そのもの
int nRows, nCols; // 行/列数
// 新しい行列作成
void NewMatrix(int rows, int cols)
{
if( entity != nullptr )
{
delete[] elements;
delete[] entity;
}
nRows = rows, nCols = cols;
entity = new int[nRows * nCols];
elements = new int*[nRows];
// elements の各行に entity の nCols * n 番目を割り当てて二次元配列を作る
for(int i=0; i<nRows; i++)
{
elements[i] = entity + (nCols * i);
}
}
// 中の行列をコピー
void SubstituteMatrix(const IntMatrix2D& srcMat)
{
for(int i=0; i<nRows; i++)
{
for(int j=0; j<nCols; j++)
{
elements[i][j] = srcMat.elements[i][j];
}
}
}
public:
// コンストラクタ
IntMatrix2D(int rows, int cols) :
entity(nullptr)
{
NewMatrix(rows, cols);
}
// コピーコンストラクタ
IntMatrix2D(const IntMatrix2D& mat) :
entity(nullptr)
{
NewMatrix(mat.nRows, mat.nCols);
SubstituteMatrix(mat);
}
// デストラクタ
~IntMatrix2D()
{
delete[] elements;
delete[] entity;
}
// 代入
IntMatrix2D& operator=(const IntMatrix2D& mat)
{
SubstituteMatrix(mat);
return *this;
}
// 要素をゲット
int& at(int row, int col) { return elements[row][col]; }
// ゼロセット
void ZeroMatrix()
{
for(int i=0; i<nRows; i++)
{
for(int j=0; j<nCols; j++)
{
elements[i][j] = 0;
}
}
}
// 転置
IntMatrix2D& Transpose()
{
IntMatrix2D OldMatrix(*this);
NewMatrix(OldMatrix.nCols, OldMatrix.nRows);
for(int i=0; i<nRows; i++)
{
for(int j=0; j<nCols; j++)
{
elements[i][j] = OldMatrix.elements[j][i];
}
}
return *this;
}
// 表示
void Show()
{
for(int i=0; i<nRows; i++)
{
for(int j=0; j<nCols; j++)
{
printf("%d ", elements[i][j] );
}
printf("\n");
}
printf("\n");
}
// 添え字演算子は使うことができない
// int& operator[](int pos)
// {
// return *(*elements+pos);
// }
};
ごちゃごちゃするけど、long int とか double で使うためにテンプレートで書くと下記のようになります。
コード:
template<class T>
class Matrix2D
{
private:
T* entity;
T** elements;
int nRows, nCols;
void NewMatrix(int rows, int cols);
void SubstituteMatrix(const Matrix2D& srcMat);
public:
Matrix2D(int rows, int cols);
Matrix2D(const Matrix2D& mat);
~Matrix2D();
Matrix2D& operator=(const Matrix2D& mat);
T& at(int row, int col);
void ZeroMatrix();
Matrix2D& Transpose();
void Show();
};
template <class T>
void Matrix2D<T>::NewMatrix(int rows, int cols)
{
if( entity != nullptr )
{
delete[] elements;
delete[] entity;
}
nRows = rows, nCols = cols;
entity = new T[nRows * nCols];
elements = new T*[nRows];
for(int i=0; i<nRows; i++)
{
elements[i] = entity + (nCols * i);
}
}
template <class T>
void Matrix2D<T>::SubstituteMatrix(const Matrix2D& srcMat)
{
for(int i=0; i<nRows; i++)
{
for(int j=0; j<nCols; j++)
{
elements[i][j] = srcMat.elements[i][j];
}
}
}
template <class T>
Matrix2D<T>::Matrix2D(int rows, int cols) :
entity(nullptr)
{
NewMatrix(rows, cols);
}
template <class T>
Matrix2D<T>::Matrix2D(const Matrix2D& mat) :
entity(nullptr)
{
NewMatrix(mat.nRows, mat.nCols);
SubstituteMatrix(mat);
}
template <class T>
Matrix2D<T>::~Matrix2D()
{
delete[] elements;
delete[] entity;
}
template <class T>
Matrix2D<T>& Matrix2D<T>::operator=(const Matrix2D& mat)
{
SubstituteMatrix(mat);
return *this;
}
template <class T>
T& Matrix2D<T>::at(int row, int col)
{
return elements[row][col];
}
template <class T>
void Matrix2D<T>::ZeroMatrix()
{
for(int i=0; i<nRows; i++)
{
for(int j=0; j<nCols; j++)
{
elements[i][j] = 0;
}
}
}
template <class T>
Matrix2D<T>& Matrix2D<T>::Transpose()
{
Matrix2D OldMatrix(*this);
NewMatrix(OldMatrix.nCols, OldMatrix.nRows);
for(int i=0; i<nRows; i++)
{
for(int j=0; j<nCols; j++)
{
elements[i][j] = OldMatrix.elements[j][i];
}
}
return *this;
}
template <class T>
void Matrix2D<T>::Show()
{
for(int i=0; i<nRows; i++)
{
for(int j=0; j<nCols; j++)
{
printf("%d ", elements[i][j] );
}
printf("\n");
}
printf("\n");
}
イカのように使います。
コード:
int main()
{
IntMatrix2D Mat1(3, 4);
IntMatrix2D Mat2(4, 3);
Mat1.ZeroMatrix();
Mat1.at(0, 0) = 1;
Mat1.at(0, 1) = 2;
Mat1.at(0, 2) = 3;
Mat1.at(1, 2) = 4;
Mat1.Show();
Mat2 = Mat1.Transpose();
Mat2.Show();
Matrix2D<int> Mat3(3, 4);
Matrix2D<int> Mat4(4, 3);
Mat3.ZeroMatrix();
Mat3.at(0, 0) = 1;
Mat3.at(0, 1) = 2;
Mat3.at(0, 2) = 3;
Mat3.at(1, 2) = 4;
Mat3.Show();
Mat4 = Mat3.Transpose();
for(int i=0; i<4; i++)
{
for(int j=0; j<3; j++)
{
printf("%d ", Mat4.at(i, j) );
}
printf("\n");
}
printf("\n");
int a;
scanf("%d", &a);
return 0;
}
すると出力は
1 2 3 0
0 0 4 0
0 0 0 0
1 0 0
2 0 0
3 4 0
0 0 0
1 2 3 0
0 0 4 0
0 0 0 0
1 0 0
2 0 0
3 4 0
0 0 0
と出ます。あんまりよくないかもしれないですが、参考になれば嬉しいです:)