Jump to content

Matrix transposition: Difference between revisions

Add C++ generic solution
(Modify from C++ to cpp)
(Add C++ generic solution)
Line 324:
 
[3,3]((0,3,6),(1,4,7),(2,5,8))
 
===Generic solution===
 
main.cpp
<lang cpp>#include <iostream>
#include "matrix.h"
 
#if !defined(ARRAY_SIZE)
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
#endif
 
template<class T>
void printMatrix(const Matrix<T>& m) {
std::cout << "rows = " << m.rowNum() << " columns = " << m.colNum() << std::endl;
for (unsigned int i = 0; i < m.rowNum(); i++) {
for (unsigned int j = 0; j < m.colNum(); j++) {
std::cout << m[i][j] << " ";
}
std::cout << std::endl;
}
} /* printMatrix() */
 
int main() {
int am[2][3] = {
{1,2,3},
{4,5,6},
};
 
Matrix<int> a(ARRAY_SIZE(am), ARRAY_SIZE(am[0]), am[0], ARRAY_SIZE(am)*ARRAY_SIZE(am[0]));
 
try {
std::cout << "Before transposition:" << std::endl;
printMatrix(a);
std::cout << std::endl;
a.transpose();
std::cout << "After transposition:" << std::endl;
printMatrix(a);
} catch (MatrixException& e) {
std::cerr << e.message() << std::endl;
return e.errorCode();
}
 
} /* main() */</lang>
 
matrix.h
<lang cpp>#ifndef _MATRIX_H
#define _MATRIX_H
 
#include <sstream>
#include <string>
#include <vector>
#include <algorithm>
 
#define MATRIX_ERROR_CODE_COUNT 5
#define MATRIX_ERR_UNDEFINED "1 Undefined exception!"
#define MATRIX_ERR_WRONG_ROW_INDEX "2 The row index is out of range."
#define MATRIX_ERR_MUL_ROW_AND_COL_NOT_EQUAL "3 The row number of second matrix must be equal with the column number of first matrix!"
#define MATRIX_ERR_MUL_ROW_AND_COL_BE_GREATER_THAN_ZERO "4 The number of rows and columns must be greater than zero!"
#define MATRIX_ERR_TOO_FEW_DATA "5 Too few data in matrix."
 
class MatrixException {
private:
std::string message_;
int errorCode_;
public:
MatrixException(std::string message = MATRIX_ERR_UNDEFINED);
 
inline std::string message() {
return message_;
};
 
inline int errorCode() {
return errorCode_;
};
};
 
MatrixException::MatrixException(std::string message) {
errorCode_ = MATRIX_ERROR_CODE_COUNT + 1;
std::stringstream ss(message);
ss >> errorCode_;
if (errorCode_ < 1) {
errorCode_ = MATRIX_ERROR_CODE_COUNT + 1;
}
std::string::size_type pos = message.find(' ');
if (errorCode_ <= MATRIX_ERROR_CODE_COUNT && pos != std::string::npos) {
message_ = message.substr(pos + 1);
} else {
message_ = message + " (This an unknown and unsupported exception!)";
}
}
 
/**
* Generic class for matrices.
*/
template <class T>
class Matrix {
private:
std::vector<T> v; // the data of matrix
unsigned int m; // the number of rows
unsigned int n; // the number of columns
protected:
 
virtual void clear() {
v.clear();
m = n = 0;
}
public:
 
Matrix() {
clear();
}
Matrix(unsigned int, unsigned int, T* = 0, unsigned int = 0);
Matrix(unsigned int, unsigned int, const std::vector<T>&);
 
virtual ~Matrix() {
clear();
}
Matrix& operator=(const Matrix&);
std::vector<T> operator[](unsigned int) const;
Matrix operator*(const Matrix&);
void transpose();
 
inline unsigned int rowNum() const {
return m;
}
 
inline unsigned int colNum() const {
return n;
}
 
inline unsigned int size() const {
return v.size();
}
 
inline void add(const T& t) {
v.push_back(t);
}
};
 
template <class T>
Matrix<T>::Matrix(unsigned int row, unsigned int col, T* data, unsigned int dataLength) {
clear();
if (row > 0 && col > 0) {
m = row;
n = col;
unsigned int mxn = m * n;
if (dataLength && data) {
for (unsigned int i = 0; i < dataLength && i < mxn; i++) {
v.push_back(data[i]);
}
}
}
}
 
template <class T>
Matrix<T>::Matrix(unsigned int row, unsigned int col, const std::vector<T>& data) {
clear();
if (row > 0 && col > 0) {
m = row;
n = col;
unsigned int mxn = m * n;
if (data.size() > 0) {
for (unsigned int i = 0; i < mxn && i < data.size(); i++) {
v.push_back(data[i]);
}
}
}
}
 
template<class T>
Matrix<T>& Matrix<T>::operator=(const Matrix<T>& other) {
clear();
if (other.m > 0 && other.n > 0) {
m = other.m;
n = other.n;
unsigned int mxn = m * n;
for (unsigned int i = 0; i < mxn && i < other.size(); i++) {
v.push_back(other.v[i]);
}
}
return *this;
}
 
template<class T>
std::vector<T> Matrix<T>::operator[](unsigned int index) const {
std::vector<T> result;
if (index >= m) {
throw MatrixException(MATRIX_ERR_WRONG_ROW_INDEX);
} else if ((index + 1) * n > size()) {
throw MatrixException(MATRIX_ERR_TOO_FEW_DATA);
} else {
unsigned int begin = index * n;
unsigned int end = begin + n;
for (unsigned int i = begin; i < end; i++) {
result.push_back(v[i]);
}
}
return result;
}
 
template<class T>
Matrix<T> Matrix<T>::operator*(const Matrix<T>& other) {
Matrix result(m, other.n);
if (n != other.m) {
throw MatrixException(MATRIX_ERR_MUL_ROW_AND_COL_NOT_EQUAL);
} else if (m <= 0 || n <= 0 || other.n <= 0) {
throw MatrixException(MATRIX_ERR_MUL_ROW_AND_COL_BE_GREATER_THAN_ZERO);
} else if (m * n > size() || other.m * other.n > other.size()) {
throw MatrixException(MATRIX_ERR_TOO_FEW_DATA);
} else {
for (unsigned int i = 0; i < m; i++) {
for (unsigned int j = 0; j < other.n; j++) {
T temp = v[i * n] * other.v[j];
for (unsigned int k = 1; k < n; k++) {
temp += v[i * n + k] * other.v[k * other.n + j];
}
result.v.push_back(temp);
}
}
}
return result;
}
 
template<class T>
void Matrix<T>::transpose() {
if (m * n > size()) {
throw MatrixException(MATRIX_ERR_TOO_FEW_DATA);
} else {
std::vector<T> v2;
std::swap(v, v2);
for (unsigned int i = 0; i < n; i++) {
for (unsigned int j = 0; j < m; j++) {
v.push_back(v2[j * n + i]);
}
}
std::swap(m, n);
}
}
 
#endif /* _MATRIX_H */</lang>
 
Output:
<pre>Before transposition:
rows = 2 columns = 3
1 2 3
4 5 6
 
After transposition:
rows = 3 columns = 2
1 4
2 5
3 6</pre>
 
=={{header|Clojure}}==
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.