diff --git a/Matrix/main.cpp b/Matrix/main.cpp new file mode 100644 index 0000000..5d7a01f --- /dev/null +++ b/Matrix/main.cpp @@ -0,0 +1,36 @@ +#include +#include "matrix.h" +using namespace std; +/* +TO TEST: +ok matrix(int rows = 0, int cols = 0); +ok ~matrix() { delete[] element; } +ok int rowss() const { return rows; } +ok int columns() const { return cols; } +ok int times(int i, int j, matrix& left, matrix& right) const;//If unused, write it in private + T& operator()(int i, int j) const; + matrix& operator=(const matrix& x); + //matrix operator+() const; + matrix operator+(const matrix& x) const; + //matrix operator-() const; + matrix operator-(const matrix& x) const; + matrix operator*(const matrix& x) const; + matrix& operator+=(const matrix& x); + friend ostream& operator<<(const matrix& x); +*/ + +int main() { + int l[] = { 1,2,3,4,5,6 }; + matrix left(2, 3, l), right(3, 2, l); + cout << "left: " << endl << left << endl; + cout << "right: " << endl << right << endl; + + cout << "left(1, 1): " << left(1, 1) << endl; + cout << "right(2, 1): " << right(2, 1) << endl << endl; + + int out[] = { 1,2,3,4 }; + matrix tmp(2, 2, out); + tmp = left * right; + cout << "times: " << endl << tmp << endl; + return 0; +} \ No newline at end of file diff --git a/Matrix/matrix.h b/Matrix/matrix.h new file mode 100644 index 0000000..8012e89 --- /dev/null +++ b/Matrix/matrix.h @@ -0,0 +1,148 @@ +#pragma once +#include + +template +class matrix { +private: + int rows;//行 + int cols;//列 + T* element;//注意是T* 而不是T** 底层线性 +public: + matrix() = delete; + matrix(int rows = 0, int cols = 0, T* x = nullptr); + ~matrix() { delete[] element; } + int rowss() const { return rows; } + int columns() const { return cols; } + int times(int i, int j, const matrix& left, const matrix& right) const;//If unused, write it in private + T& operator()(int i, int j) const; + matrix& operator=(const matrix& x); + //matrix operator+() const; + matrix operator+(const matrix& x) const; + //matrix operator-() const; + matrix operator-(const matrix& x) const; + matrix operator*(const matrix& x) const; + matrix& operator+=(const matrix& x); + template + friend std::ostream& operator<<(std::ostream& os, const matrix& x); + + bool operator==(const matrix& other) const { + if (rows != other.rows || cols != other.cols) + return false; + for (int i = 0; i < rows * cols; ++i) + if (element[i] != other.element[i]) + return false; + return true; + } + + bool operator!=(const matrix& other) const { + return !(*this == other); + } +}; + +template +int matrix::times(int i, int j, const matrix& left, const matrix& right) const { + int tmp = 0; + for (int x = 1; x <= left.cols; x++) { + tmp += left(i, x) * right(x, j); + } + return tmp; +} + +template +matrix::matrix(int rows, int cols, T* x) : rows(rows), cols(cols){ + if (rows < 0 || cols < 0) { + throw std::out_of_range("Matrix subscript out of range"); + } + + int sum = rows * cols; + element = new T[sum]; + for (int i = 0; i < sum; i++) { + element[i] = x[i]; + } +} + +template +T& matrix::operator()(int i, int j) const { + if (i < 1 || i > rows || j < 1 || j > cols) { + throw std::out_of_range("Matrix subscript out of range"); + } + return element[(i - 1) * cols + j - 1];//important, using cols rather than rows +} + +template +matrix& matrix::operator=(const matrix& x) { + if (*this != x) { + delete[] element; + int sum = x.rows * x.cols; + element = new T[sum]; + for (int i = 0; i < sum; i++) { + element[i] = x.element[i]; + } + } + return *this; + +} + +template +matrix matrix::operator+(const matrix& x) const{ + if (rows != x.rows || cols != x.cols) { + throw std::invalid_argument("matrix can't add: size mismatch"); + } + //std::unique_ptr> tmp = std::make_unique>(rows, cols); + matrix tmp(rows, cols); + for (int i = 0; i < rows * cols; i++) { + tmp.element[i] = element[i] + x.element[i]; + } + return tmp; +} + +template +matrix matrix::operator-(const matrix& x) const { + if (rows != x.rows || cols != x.cols) { + throw std::invalid_argument("matrix can't minus: size mismatch"); + } + //std::unique_ptr> tmp = std::make_unique>(rows, cols); + matrix tmp(rows, cols); + for (int i = 0; i < rows * cols; i++) { + tmp.element[i] = element[i] - x.element[i]; + } + return tmp; +} + +template +matrix matrix::operator*(const matrix& x) const { + if (cols != x.rows) { + throw std::invalid_argument("matrix can't times: size mismatch"); + } + T* t = new T[rows * x.cols]; + matrix tmp(rows, x.cols, t); + //* is difficult : 左行右列 + for (int i = 1; i <= rows; i++) { + for (int j = 1; j <= x.cols; j++) { + tmp(i, j) = times(i, j, *this, x); + } + } + return tmp; +} + +template +matrix& matrix::operator+=(const matrix& x) { + if (rows != x.rows || cols != x.cols) { + throw std::invalid_argument("matrix += error: size mismatch"); + } + for (int i = 0; i < rows * cols; i++) { + element[i] += x.element[i]; + } + return *this; +} + +template +std::ostream& operator<<(std::ostream& os, const matrix& x) { + for (int i = 0; i < x.rows; i++) { + for (int j = 0; j < x.cols; j++) { + os << x.element[i * x.cols + j] << " "; + } + os << std::endl; + } + return os; +}