使用一维vector实现矩阵类模板
虽然这个矩阵类是以一维数组的形式实现的(无奈,作业要求),但还是有些东西值得记录和复用
题目
-
Design a template class Matrix that has the following private member variables:
- int rows
- int columns
- vector
values
, where T is the type parameter.
Besides, it has the functions such that the main function runs correctly with the following output.
EXAMPLE OUTPUT
constructor 1
0 0 0
0 0 0
0 0 0
constructor 2
1 2 3
4 5 6
7 8 9
copy constructor
1 2 3
4 5 6
7 8 9
operator =
1 2 3
4 5 6
7 8 9
getColumn
2
5
8
getRow
4 5 6
concatenateRows
0 0 0
0 0 0
0 0 0
1 2 3
4 5 6
7 8 9
concatenateColumns
0 0 0 1 2 3
0 0 0 4 5 6
0 0 0 7 8 9
reshape
0 0 2
0 0 5
0 0 8
0 1 3
0 4 6
0 7 9
transpose
1 4 7
2 5 8
3 6 9
operator +
2 4 6
8 10 12
14 16 18
operator +
11 12 13
14 15 16
17 18 19
operator -
0 2 4
-2 0 2
-4 -2 0
operator -
-9 -8 -7
-6 -5 -4
-3 -2 -1
operator *
66 78 90
78 93 108
90 108 126
operator *
2 4 6
8 10 12
14 16 18
max
9
min
1
sum
45
代码实现
#include <vector>
#include <iostream>
#include <string.h>
#define INF 0x7f7f7f7f
using namespace std;
template<typename T>
class Matrix
{
private:
int rows;
int columns;
vector<T> values;
public:
Matrix(int x,int y){
rows=x;
columns=y;
for(int i =0 ; i < rows*columns; i++)values.push_back(0);
}
Matrix(int x,int y,const vector<T>val){
rows=x;
columns=y;
for(int i=0;i<rows*columns;i++){
values.push_back(val[i]);
}
}
~Matrix(){
values.clear();
}
Matrix(const Matrix<T>&mat){
values.clear();
rows=mat.rows;
columns=mat.columns;
for(int i=0;i<rows*columns;i++){
values.push_back(mat.values[i]);
}
}
void print(){
for(int i=0;i<rows;i++){
for(int j=0;j<columns;j++){
cout<<" ";
cout<<values[i*columns+j];
}
cout<<endl;
}
}
Matrix &operator =(const Matrix&mat){
values.clear();
rows = mat.rows;
columns=mat.columns;
for(int i=0;i<rows*columns;i++){
values.push_back(mat.values[i]);
}
return *this;
}
T &get(int x,int y){
return values[(x-1)*columns+y-1];
}
Matrix transpose() {
vector<T> newarr;
for(int i = 0; i < columns; i++){
for(int j = 0; j < rows; j++){
newarr.push_back(values[j*(columns)+i]) ;
}
}
return Matrix(columns, rows, newarr);
}
//坐标表示法 (row-1)*columns+column-1
Matrix operator * (const Matrix<T> & matrix2) const{
vector<T> arr;
for(int i = 0; i < rows*columns; i++)arr.push_back(0);
for(int i = 0; i < this->rows; i ++){
for(int j = 0; j < matrix2.columns; j ++){
for (int l = 0, m = 0; l < matrix2.rows; l++,m++){
arr[i*matrix2.columns+j] += this->values[i*this->columns+l] * matrix2.values[m * matrix2.columns+j];
}
}
}
Matrix<T> newmatrix(rows, matrix2.columns, arr);
return newmatrix;
}
Matrix operator * (T value) const{
vector<T> arr;
for(int i = 0; i < rows*columns; i++)arr.push_back(0);
for(int i = 0; i < rows*columns; i++){
arr[i] = value * values[i];
}
return Matrix<T>(rows, columns, arr);
}
Matrix operator + (T value) const{
vector<T> arr;
for(int i = 0; i < rows*columns; i++)arr.push_back(0);
for(int i = 0; i < rows*columns; i++){
arr[i] = value + values[i];
}
return Matrix<T>(rows, columns, arr);
}
Matrix operator + (const Matrix<T> & matrix2) const{
vector<T> arr;
for(int i = 0; i < rows*columns; i++)arr.push_back(0);
for(int i = 0; i < rows*columns; i++)arr[i] = values[i]+matrix2.values[i];
return Matrix<T> (rows,columns,arr);
}
Matrix operator - (T value) const{
vector<T> arr;
for(int i = 0; i < rows*columns; i++)arr.push_back(0);
for(int i = 0; i < rows*columns; i++){
arr[i] = values[i] - value;
}
return Matrix<T>(rows, columns, arr);
}
Matrix operator - (const Matrix<T> & matrix2) const{
vector<T> arr;
for(int i = 0; i < rows*columns; i++)arr.push_back(0);
for(int i = 0; i < rows*columns; i++)arr[i] = values[i]-matrix2.values[i];
return Matrix<T> (rows,columns,arr);
}
Matrix max() const{
if(rows>1){
vector<T> newarr;
for(int i = 0; i < rows*columns; i++)newarr.push_back(0);
int max,maxrows;
for(int i = 0; i < this->columns;i++){
max = 0;
maxrows = 0;
for(int j = 0 ;j < this->rows; j++){
if(values[columns*j+i]>max){
max = values[columns*j+i];
maxrows = j;
}
}
newarr[i] = values[this->columns*maxrows + i];
}
return Matrix(1,columns,newarr);
}
if(rows==1){
int max = 0;
for(int i = 0; i < columns; i++){
if(values[i] > max)max = values[i];
}
vector<T> newarr;
newarr.push_back(0);
newarr[0] = max;
return Matrix(1,1,newarr);
}
}
Matrix min() const{
if(rows>1){
vector<T> newarr;
for(int i = 0; i < rows*columns; i++)newarr.push_back(0);
int min,minrows;
for(int i = 0; i < this->columns;i++){
min = INF;
minrows = 0;
for(int j = 0 ;j < this->rows; j++){
if(values[columns*j+i]<min){
min = values[columns*j+i];
minrows = j;
}
}
newarr[i] = this->values[this->columns*minrows + i];
}
return Matrix(1,columns,newarr);
}
if(rows==1){
int min = INF;
for(int i = 0; i < columns; i++){
if(values[i] < min)min = values[i];
}
vector<T> newarr;
newarr.push_back(0);
newarr[0] = min;
return Matrix(1,1,newarr);
}
}
Matrix sum() const {
if(rows>1){
vector<T> newarr;
for(int i = 0; i < rows*columns; i++)newarr.push_back(0);
int sum;
for(int i = 0; i < this->columns;i++){
sum = 0;
for(int j = 0 ;j < this->rows; j++){
sum += values[columns*j+i];
}
newarr[i] = sum;
}
return Matrix(1,columns,newarr);
}
if(rows==1){
int sum = 0;
for(int i = 0; i < columns; i++){
sum += values[i];
}
vector<T> newarr;
newarr.push_back(0);
newarr[0] = sum;
return Matrix(1,1,newarr);
}
}
Matrix concatenateRows(const Matrix & matrix2)const {
vector<T> newarr;
for(int i = 0; i < rows*columns*2; i++)newarr.push_back(0);
for(int i = 0 ; i < this->rows*this->columns; i++){
newarr[i] = this->values[i];
}
for(int i = 0 ; i < this->rows*this->columns; i++){
newarr[i+this->rows*this->columns] = matrix2.values[i];
}
return Matrix(rows*2,columns,newarr);
}
Matrix concatenateColumns(const Matrix & matrix2) const{
vector<T> newarr;
for(int i = 0; i < rows*columns*2; i++)newarr.push_back(0);
int cnt = 0;
int cnt1 = 0, cnt2 = 0;
for(int i = 0; i < this->rows; i++){
for(int j = 0; j < this->columns; j++, cnt1++,cnt++){
newarr[cnt] = this->values[cnt1];
}
for(int j = 0; j < this->columns; j++,cnt2++,cnt++){
newarr[cnt] = matrix2.values[cnt2];
}
}
return Matrix(rows,columns*2,newarr);
}
Matrix getRow(int row){
vector<T> newarr;
for(int i = 0; i < columns; i++)newarr.push_back(0);
for(int i = 0; i < columns; i++)newarr[i] = values[(row-1)*columns+i];
return Matrix(1, this->columns, newarr);
}
Matrix getColumn(int column){
vector<T> newarr;
for(int i = 0; i < rows; i++)newarr.push_back(0);
for(int i = 0; i < this->rows; i ++){
newarr[i] = this->values[column-1+ i*this->columns];
}
return Matrix(this->rows,1, newarr);
}
Matrix reshape(int x,int y){
vector<T> newarr;
for(int i = 0; i < rows*columns; i++)newarr.push_back(0);
vector<T> temp;
for(int i = 0; i < columns; i++){
for(int j = 0; j < rows; j++){
temp.push_back(values[columns*j+i]);
}
}
int cnt = 0;
for(int i = 0; i < y; i++){
for(int j = 0; j < x; j++,cnt++){
newarr[y*j+i] = temp[cnt];
}
}
return Matrix<T>(columns, rows, newarr);
}
};
int main() {
cout << "constructor 1" << endl;
Matrix<double> matrix1(3, 3);
matrix1.print();
const double values1[] = {
1, 2, 3,
4, 5, 6,
7, 8, 9,
};
vector<double> values2;
for (int i = 0; i < 9; ++ i) {
values2.push_back(values1[i]);
}
cout << "constructor 2" << endl;
Matrix<double> matrix2(3, 3, values2);
matrix2.print();
cout << "copy constructor" << endl;
Matrix<double> matrix3 = matrix2;
matrix3.print();
cout << "operator =" << endl;
matrix3.get(1, 1) = 10.0;
matrix3 = matrix2;
matrix3.print();
cout << "getColumn" << endl;
matrix2.getColumn(2).print();
cout << "getRow" << endl;
matrix2.getRow(2).print();
cout << "concatenateRows" << endl;
matrix1.concatenateRows(matrix2).print();
cout << "concatenateColumns" << endl;
matrix1.concatenateColumns(matrix2).print();
cout << "reshape" << endl;
matrix1.concatenateColumns(matrix2).
reshape(6, 3).print();
cout << "transpose" << endl;
matrix2.transpose().print();
cout << "operator +" << endl;
(matrix2 + matrix2).print();
cout << "operator +" << endl;
(matrix2 + 10).print();
cout << "operator -" << endl;
(matrix2.transpose() - matrix2).print();
cout << "operator -" << endl;
(matrix2 - 10).print();
cout << "operator *" << endl;
(matrix2.transpose() * matrix2).print();
cout << "operator *" << endl;
(matrix2 * 2).print();
cout << "max" << endl;
cout << matrix2.max().max().get(1, 1) << endl;
cout << "min" << endl;
cout << matrix2.min().min().get(1, 1) << endl;
cout << "sum" << endl;
cout << matrix2.sum().sum().get(1, 1) << endl;
}