Last active
February 27, 2020 16:40
-
-
Save vladimir-vg/e86bf9fd4eedda02fd9373ed2437b4dd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
using namespace std; | |
class Matrix { | |
public: | |
int row = 0; | |
int column = 0; | |
// ты хранишь данные таблицы как массив указателей на массивы | |
// это значит что когда ты создаёшь новую матрицу, | |
// тебе нужно создавать новый массив, делать new. | |
// тупое присваивание будет работать неправильно | |
double **arr = NULL; | |
Matrix(){ | |
this->row = 0; | |
this->column = 0; | |
this->arr = NULL;}; | |
Matrix(int r, int c){ | |
this->row = r; | |
this->column = c; | |
// всё правильно, создаёшь новые массивы | |
this->arr = new double*[row]; | |
for (int i = 0; i < row; i++) { | |
arr[i] = new double[column]; | |
} | |
} | |
friend istream& operator>>(istream &input, const Matrix &matrix) { | |
for (int i = 0; i < matrix.row; i++) { | |
for (int j = 0; j < matrix.column; j++) { | |
input >> matrix.arr[i][j]; | |
} | |
} | |
return input; | |
} | |
Matrix& operator=(Matrix& B) { | |
this->row = B.row; | |
this->column = B.column; | |
// так делать нельзя. Ты сохранила указатель на массив, а не сам массив | |
// теперь у тебя две разные матрицы пользуются одним и тем же куском памяти | |
// тебе нужно здесь создавать новый массив через new, также как и в конструкторе | |
this->arr = B.arr; | |
for (int i = 0; i < B.row; i++) { | |
// здесь то же самое | |
this->arr[i] = B.arr[i]; | |
} | |
for (int i = 0; i < B.row; i++) { | |
for (int j = 0; j < B.column; j++) { | |
this->arr[i][j] = B.arr[i][j]; | |
} | |
} | |
return (*this); | |
} | |
friend ostream& operator<<(ostream &output, Matrix &matrix) { | |
for (int i = 0; i < matrix.row; i++) { | |
for (int j = 0; j < matrix.column; j++) { | |
output << matrix.arr[i][j]; | |
if (j+1<matrix.column) { | |
output <<" "; | |
} | |
} | |
if (i+1<matrix.row) { | |
output <<endl; | |
} | |
} | |
return output; | |
} | |
Matrix operator+(Matrix& B) { | |
Matrix A(row, column); | |
for (int i = 0; i < row; i++) { | |
for (int j = 0; j < column; j++) { | |
A.arr[i][j] = arr[i][j] + B.arr[i][j]; | |
} | |
} | |
return(A); | |
} | |
Matrix operator-(Matrix& B) { | |
Matrix A(row,column); | |
for (int i = 0; i < row; i++) { | |
for (int j = 0; j < column; j++) { | |
A.arr[i][j] = arr[i][j] - B.arr[i][j]; | |
} | |
} | |
return(A); | |
} | |
friend Matrix transposed(Matrix& matrix) { | |
Matrix *B = new Matrix(); | |
B->row = matrix.column; | |
B->column = matrix.row; | |
B->arr = new double*[B->row]; | |
for (int i = 0; i < B->row; i++) { | |
B->arr[i] = new double[B->column]; | |
for (int j =0; j < B->column; j++) { | |
B->arr[i][j] = matrix.arr[j][i]; | |
} | |
} | |
return (*B); | |
} | |
Matrix transposed() { | |
Matrix* m1 = new Matrix(); | |
m1->row = this->row; | |
m1->column = this->column; | |
m1->arr = new double*[this->row]; | |
for (int i = 0; i < m1->row; i++) { | |
m1->arr[i] = new double[m1->column]; | |
for (int j = 0; j < m1->column; j++) { | |
m1->arr[i][j] = this->arr[j][i]; | |
} | |
} | |
return(*m1); | |
} | |
Matrix operator*(Matrix& B) { | |
Matrix A(row,B.column); | |
for (int i = 0; i < row; i++) { | |
for (int j = 0; j < B.column; j++) { | |
double m = 0; | |
for (int k = 0; k < B.row; k++) { | |
m = m + (arr[i][k])*(B.arr[k][j]); | |
} | |
A.arr[i][j] = m; | |
} | |
} | |
return A; | |
} | |
}; | |
class Square_Matrix: public Matrix { | |
public: | |
int size_m; | |
Square_Matrix(int s) : Matrix(s,s) { | |
this->size_m = s; | |
} | |
Square_Matrix& operator=(Square_Matrix& B) { | |
this->row = B.row; | |
this->column = B.column; | |
this->size_m = B.size_m; | |
// Здесь та же проблема: у тебя текущая матрица будет указывать на данные в B | |
// если в B что-то поменяется, то и в this->arr тоже | |
// правильно здесь создавать новый массив и копировать | |
this->arr = B.arr; | |
for (int i = 0; i < B.row; i++) { | |
// то же самое | |
this->arr[i] = B.arr[i]; | |
} | |
for (int i = 0; i < B.row; i++) { | |
for (int j = 0; j < B.column; j++) { | |
this->arr[i][j] = B.arr[i][j]; | |
} | |
} | |
return (*this); | |
} | |
Square_Matrix operator+(Square_Matrix& B) { | |
Matrix* A1 = this; | |
Matrix* B1 = (Matrix*)&B; | |
Matrix S1 = (*A1) + (*B1); | |
Square_Matrix *mat = (Square_Matrix*) &S1; | |
return *mat; | |
} | |
Square_Matrix operator-(Square_Matrix& B) { | |
Matrix* A1 = this; | |
Matrix* B1 = (Matrix*)&B; | |
Matrix S1 = (*A1) - (*B1); | |
Square_Matrix *mat = (Square_Matrix*) &S1; | |
return *mat; | |
} | |
Square_Matrix operator*(Square_Matrix& B) { | |
Matrix* m1 = this; | |
Matrix* m2 = (Matrix*)&B; | |
Matrix s1 = (*m1) * (*m2); | |
Square_Matrix *mat = (Square_Matrix*)&s1; | |
return *mat; | |
} | |
Square_Matrix transposed() { | |
Matrix* m1 = this; | |
Matrix m2 = (*m1).transposed(); | |
Square_Matrix* s1 = (Square_Matrix*)&m2; | |
return (*s1); | |
} | |
double abs (double &element) { | |
if (element < 0) { | |
return (-element); | |
} | |
return element; | |
} | |
int find_max (Square_Matrix &M, int col) { | |
int max_ij = M.arr[col][col]; | |
int max_row = col; | |
for (int i = col+1; i < size_m; i++) { | |
if (abs(M.arr[i][col]) > max_ij) { | |
max_ij = abs(M.arr[i][col]); | |
max_row = i; | |
} | |
} | |
return max_row; | |
} | |
}; | |
class Identity_Matrix : public Square_Matrix { | |
public: | |
Identity_Matrix(int s) : Square_Matrix(s) { | |
for (int i = 0; i < row; i++) { | |
arr[i] = new double[column]; | |
for (int j = 0; j < column; j++) { | |
if (i==j) { | |
arr[i][j] = 1; | |
} | |
else { | |
arr[i][j] = 0; | |
} | |
} | |
} | |
} | |
}; | |
class Elimination_Matrix : public Identity_Matrix { | |
public: | |
int r; | |
int c; | |
Elimination_Matrix(int s, int r1, int c1, Matrix& M) : Identity_Matrix(s) { | |
this->r = r1; | |
this->c = c1; | |
this->arr[r][c] = - (M.arr[r][c]/M.arr[c][c]); | |
} | |
Square_Matrix operator*(Square_Matrix& B) { | |
Square_Matrix* m1 = this; | |
Square_Matrix s1 = ((*m1) * B); | |
//Square_Matrix *mat = s1; | |
return s1; | |
} | |
}; | |
class Permutation_Matrix : public Identity_Matrix { | |
int row1; | |
int row2; | |
public: | |
Permutation_Matrix(int s, int r1, int r2) : Identity_Matrix(s) { | |
this->row1 = r1; | |
this->row2 = r2; | |
this->arr[row1][row2] = 1; | |
this->arr[row2][row1] = 1; | |
this->arr[row1][row1] = 0; | |
this->arr[row2][row2] = 0; | |
} | |
Square_Matrix operator*(Square_Matrix& B) { | |
Square_Matrix* m1 = this; | |
Square_Matrix s1 = ((*m1) * B); | |
return s1; | |
} | |
}; | |
int main() | |
{ | |
int n,m; | |
cin>>n; | |
Square_Matrix A(n); | |
cin >> A; | |
int n_step = 1; | |
for (int i = 0; i < A.size_m; i++) { | |
int swapt = A.find_max(A, i); | |
if (swapt != i) { | |
Permutation_Matrix P(n, i, swapt); | |
Square_Matrix m = P*A; | |
A = m; | |
cout << "step #" << n_step << ": permutation" <<endl; | |
cout << A <<endl; | |
} | |
for (int j = i+1; j < n; j++) { | |
Elimination_Matrix E(n,j,i, A); | |
Square_Matrix m = E*A; | |
A = m; | |
cout << "step #" << n_step << ": elimination" <<endl; | |
cout << A <<endl; | |
n_step++; | |
} | |
} | |
int result = 1; | |
for (int i = 0; i < n; i++) { | |
result = result*A.arr[i][i]; | |
} | |
cout << "result:" << endl; | |
cout << result; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment