Pre-end version

This commit is contained in:
gandc committed 2024-05-10 19:52:53 +03:00
1 parent 91245c1cfe
commit 56d58f4d28
1 file changed
+367 -213
+367 -213
View File
@@ -1,244 +1,398 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <typeinfo> #include<string.h>
#include <cstring> #include <cstdlib>
#include <utility> #include <ctime>
#include <tuple>
using namespace std; using namespace std;
class Exception: public exception /*class Exception: public exception
{ {
protected: protected:
// Сообщение об ошибке //????????? ?? ??????
char* str; char* str;
public: public:
Exception(const char* s) Exception(const char* s)
{ {
str = new char[strlen(s) + 1]; str = new char[strlen(s) + 1];
strcpy(str, s); strcpy_s(str, strlen(s) + 1, s);
} }
Exception(const Exception& e) Exception(const Exception& e)
{ {
str = new char[strlen(e.str) + 1]; str = new char[strlen(e.str) + 1];
strcpy(str, e.str); strcpy_s(str, strlen(e.str) + 1, e.str);
} }
~Exception() ~Exception()
{ {
delete[] str; delete[] str;
} }
// Функцию вывода можно будет переопределить в производных
// классах, когда будет ясна конкретика virtual void print()
virtual void print() {
{ cout << "Exception: " << str<< "; "<<what();
cout << "Exception: " << str; }
} };*/
class Exception : public exception
{
protected:
char* str;
public:
Exception(const char* s)
{
str = new char[strlen(s) + 1];
strcpy_s(str, strlen(s) + 1, s);
}
Exception(const Exception& e)
{
str = new char[strlen(e.str) + 1];
strcpy_s(str, strlen(e.str) + 1, e.str);
}
~Exception()
{
delete[] str;
}
virtual void print()
{
cout << "Exception: " << str << "; " << what();
}
};
class InvalidOperationException : public Exception {
public:
InvalidOperationException(const char* s) : Exception(s) {}
virtual void print()
{
cout << "InvalidOperationException: " << str << "; " << what();
}
}; };
class WrongSizeException : public Exception
{
protected:
int Row1, Col1, Row2, Col2;
public:
WrongSizeException(const char* s, int row1, int col1, int row2, int col2) : Exception(s) { Row1 = row1; Col1 = col1; Row2 = row2; Col2 = col2; }
virtual void print()
{
cout << "WrongSizeException: " << str << "; " << Row1 << ", " << Col1 << ", " << Row2 << ", " << Col2 << "; " << what();
}
};
class IndexOutOfBoundsException : public Exception
{
protected:
int Row, Col;
public:
IndexOutOfBoundsException(const char* s, int row, int col) : Exception(s) { Row = row; Col = col; }
virtual void print()
{
cout << "IndexOutOfBoundsException: " << str << "; " << Row << ", " << Col << "; " << what();
}
};
class NonPositiveSizeException : public WrongSizeException {
public:
NonPositiveSizeException(const char* s, int row1, int col1, int row2, int col2) : WrongSizeException(s, row1, col1, row2, col2) {}
virtual void print()
{
cout << "NonPositiveSizeException: " << str << "; " << Row1 << ", " << Col1 << ", " << Row2 << ", " << Col2 << "; " << what();
}
};
class TooLargeSizeException : public WrongSizeException {
public:
TooLargeSizeException(const char* s, int row1, int col1, int row2, int col2) : WrongSizeException(s, row1, col1, row2, col2) {}
virtual void print()
{
cout << "TooLargeSizeException: " << str << "; " << Row1 << ", " << Col1 << ", " << Row2 << ", " << Col2 << "; " << what();
}
};
template<class T>
class BaseMatrix class BaseMatrix
{ {
protected: protected:
double** ptr; T** ptr;
int height; int height;
int width; int width;
public: public:
BaseMatrix(int Height = 2, int Width = 2) BaseMatrix(int Height = 2, int Width = 2)
{ {
if (Height <= 0 || Width <= 0) if (Height <= 0 || Width <= 0) {
throw Exception("Non-positive size of matrix"); throw NonPositiveSizeException("Attempt to create a matrix of negative or zero size", Height, Width, -1, -1);
height = Height; }
width = Width; height = Height;
ptr = new double*[height]; width = Width;
for (int i = 0; i < height; i++) ptr = new T* [height];
ptr[i] = new double[width]; for (int i = 0; i < height; i++)
} ptr[i] = new T[width];
}
BaseMatrix(const BaseMatrix& M) : height(M.height), width(M.width) BaseMatrix(const BaseMatrix& M)
{ {
ptr = new double*[height]; height = M.height;
for (int i = 0; i < height; i++) width = M.width;
{ ptr = new T* [height];
ptr[i] = new double[width]; for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++) {
ptr[i][j] = M.ptr[i][j]; ptr[i] = new T[width];
} for (int j = 0; j < width; j++)
} ptr[i][j] = M.ptr[i][j];
}
}
BaseMatrix(double** arr, int Height, int Width) : height(Height), width(Width) BaseMatrix operator=(BaseMatrix& V)
{ {
ptr = new double*[height]; if (height != V.height && width != V.width)
for (int i = 0; i < height; i++) {
{ if (ptr != NULL)
ptr[i] = new double[width]; {
for (int j = 0; j < width; j++) for (int i = 0; i < height; i++)
ptr[i][j] = arr[i][j]; delete[] ptr[i];
} delete[] ptr;
} ptr = NULL;
}
height = V.height;
width = V.width;
ptr = new double* [height];
for (int i = 0; i < height; i++)
ptr[i] = new double[width];
}
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
ptr[i][j] = V.ptr[i][j];
return *this;
}
~BaseMatrix() ~BaseMatrix()
{ {
if (ptr != NULL) if (ptr != NULL)
{ {
for (int i = 0; i < height; i++) for (int i = 0; i < height; i++)
delete[] ptr[i]; delete[] ptr[i];
delete[] ptr; delete[] ptr;
ptr = NULL; ptr = NULL;
} }
} }
void print() void print()
{ {
for (int i = 0; i < height; i++) for (int i = 0; i < height; i++)
{ {
for (int j = 0; j < width; j++) for (int j = 0; j < width; j++)
cout << ptr[i][j] << " "; cout << ptr[i][j] << " ";
cout << "\n"; cout << "\n";
} }
} }
double& operator()(int row, int column) double& operator()(int row, int col)
{ {
if (row < 0 || column < 0 || row >= height || column >= width) if (row < 0 || col < 0 || row >= height || col >= width)
throw Exception("Index is out of bounds"); throw IndexOutOfBoundsException("IndexOutOfBoundsException in operator()", row, col);
return ptr[row][column]; return ptr[row][col];
} }
BaseMatrix& operator=(const BaseMatrix& other)
{
if (this != &other)
{
for (int i = 0; i < height; i++)
delete[] ptr[i];
delete[] ptr;
height = other.height;
width = other.width;
ptr = new double*[height];
for (int i = 0; i < height; i++)
{
ptr[i] = new double[width];
for (int j = 0; j < width; j++)
ptr[i][j] = other.ptr[i][j];
}
}
return *this;
}
friend ostream& operator<<(ostream& ustream, BaseMatrix obj);
friend istream& operator>>(istream& ustream, BaseMatrix& obj);
}; };
template <class T>
ostream& operator<<(ostream& ustream, BaseMatrix obj) class Matrix : public BaseMatrix<T>
{
if (typeid(ustream).name() == typeid(ofstream).name())
{
ustream << obj.height << " " << obj.width << "\n";
for (int i = 0; i < obj.height; i++)
{
for (int j = 0; j < obj.width; j++)
ustream << obj.ptr[i][j] << "\n";
}
return ustream;
}
for (int i = 0; i < obj.height; i++)
{
for (int j = 0; j < obj.width; j++)
ustream << obj.ptr[i][j] << " ";
ustream << "\n";
}
return ustream;
}
istream& operator>>(istream& ustream, BaseMatrix& obj)
{
if (typeid(ustream) == typeid(ifstream))
ustream >> obj.height >> obj.width;
for (int i = 0; i < obj.height; i++)
for (int j = 0; j < obj.width; j++)
ustream >> obj.ptr[i][j];
return ustream;
}
class MultidimensionalArray : public BaseMatrix
{ {
public: public:
MultidimensionalArray(int Height = 2, int Width = 2) : BaseMatrix(Height, Width) {} using BaseMatrix<T>::ptr;
using BaseMatrix<T>::height;
using BaseMatrix<T>::width;
Matrix(int Height = 2, int Width = 2) : BaseMatrix<T>(Height, Width) { cout << "\nMatrix constructor\n"; }
~Matrix() { cout << "\nMatrix destructor\n"; }
Matrix(T** array, int Height, int Width) : BaseMatrix<T>(Height, Width) {
ptr = new T* [height];
for (int i = 0; i < height; ++i) {
ptr[i] = new T[width];
for (int j = 0; j < width; ++j) {
ptr[i][j] = array[i][j];
}
}
}
// Filling a matrix element by the sum of its indices
void fillRandom(int a) {
// Initialization of random number generator with current time
srand(time(nullptr));
MultidimensionalArray(const MultidimensionalArray& M) : BaseMatrix(M) {} for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
// Random number generation
ptr[i][j] = (rand() * (a + 1))%100;
}
}
}
MultidimensionalArray(double** arr, int Height, int Width) : BaseMatrix(arr, Height, Width) {}
MultidimensionalArray& operator=(const MultidimensionalArray& other) pair<double, double> calculateCenterOfMass() {
{ double totalMass = 0;
BaseMatrix::operator=(other); double centerX = 0;
return *this; double centerY = 0;
}
pair<double, double> calculateCenterOfMass() for (int i = 0; i < this->height; ++i) {
{ for (int j = 0; j < this->width; ++j) {
double totalMass = 0.0; totalMass += this->ptr[i][j];
double weightedSumX = 0.0; centerX += i * this->ptr[i][j];
double weightedSumY = 0.0; centerY += j * this->ptr[i][j];
}
}
if (totalMass != 0) {
centerX /= totalMass;
centerY /= totalMass;
}
return make_pair(centerX, centerY);
}
for (int i = 0; i < height; ++i)
{
for (int j = 0; j < width; ++j)
{
double mass = ptr[i][j];
totalMass += mass;
weightedSumX += j * mass; // умножаем координату на массу
weightedSumY += i * mass; // умножаем координату на массу
}
}
if (totalMass == 0.0) double Trace()
{ {
return make_pair(-1.0, -1.0); // Или другое значение по умолчанию if (height != width) {
} throw InvalidOperationException("The operation of finding the trace is not defined for a non-square matrix");
}
double summ = 0;
for (int i = 0; i < height; i++)
summ += ptr[i][i];
return summ;
}
double centerX = weightedSumX / totalMass; Matrix operator+(Matrix M)
double centerY = weightedSumY / totalMass; {
if (height != M.height || width != M.width)
throw WrongSizeException("Unequal size of matrices to add in operator+()", height, width, M.height, M.width);
Matrix res(height, width);
for (int i = 0; i < height; i++)
for (int j = 0; j < width; j++)
res(i, j) = ptr[i][j] + M.ptr[i][j];
return res;
}
// Перегрузка оператора присваивания
Matrix& operator=(const Matrix& other) {
if (this != &other) {
this->~Matrix();
return make_pair(centerX, centerY); height = other.height;
} width = other.width;
ptr = new double* [height];
for (int i = 0; i < height; ++i) {
ptr[i] = new double[width];
for (int j = 0; j < width; ++j) {
ptr[i][j] = other.ptr[i][j];
}
}
}
return *this;
}
template<class T>
friend ostream& operator<<(ostream& s, Matrix<T> M);
template<class T>
friend istream& operator>>(istream& s, Matrix<T>& M);
}; };
template<class T>
int main() ostream& operator<<(ostream& s, Matrix<T> M)
{ {
try if (typeid(s) == typeid(ofstream))
{ {
MultidimensionalArray Wrong(-2, 0); s << M.height << " " << M.width << " ";
} for (int i = 0; i < M.height; i++)
catch (Exception e) for (int j = 0; j < M.width; j++)
{ s << M.ptr[i][j] << " ";
cout << "\nException has been caught: "; return s;
e.print(); }
} for (int i = 0; i < M.height; i++)
{
cout << "\n"; for (int j = 0; j < M.width; j++)
s << M.ptr[i][j] << " ";
MultidimensionalArray M; s << "\n";
cin >> M; }
return s;
ofstream fout("out.txt"); }
if (fout.is_open()) template<class T>
{ istream& operator>>(istream& s, Matrix<T>& M)
fout << M; {
fout.close(); if (typeid(s) == typeid(ifstream))
} {
int w, h; s >> h >> w;
ifstream fin("out.txt"); if (h != M.height || w != M.width)
MultidimensionalArray M1; {
if (fin) throw InvalidOperationException("The dimensions of the read matrix are different from those of the original matrix.");
{ }
fin >> M1; }
fin.close(); for (int i = 0; i < M.height; i++)
} for (int j = 0; j < M.width; j++)
s >> M.ptr[i][j];
cout << M1; return s;
}
char c1;
cin >> c1; int main() {
try {
return 0; Matrix<double> M[10];
// Matrix filling and output
for (int i = 0; i < 3; i++) {
cout << "Matrix " << i + 1 << ":" << endl;
M[i].fillRandom(i);
cout << M[i] << endl;
}
// Saving a matrix array to a file
ofstream fout("1.txt");
if (fout) {
fout << "3\n";
for (int i = 0; i < 3; i++)
fout << M[i] << "\n";
fout.close();
}
// reading a matrix array from a file
Matrix<double>* M1;
ifstream fin("1.txt");
if (fin) {
int n;
fin >> n;
M1 = new Matrix<double>[n];
for (int i = 0; i < 3; i++) {
fin >> M1[i];
cout << "Matrix from file " << i + 1 << ":" << endl;
cout << M1[i] << endl;
}
delete[] M1;
}
Matrix<double> A(2, 2);
A.fillRandom(4);
A.print();
Matrix<double> B(2, 2);
B.fillRandom(3);
B.print();
Matrix<double> C = A + B; // matrix1+matrix2
cout << "A + B:" << endl << C << endl;
Matrix<double> D;
D = A; //Assignment of matrix
cout << "D (assigned from A):" << endl << D << endl;
double a, b;
A.print();
tie(a,b)=A.calculateCenterOfMass(); //calculate Center Of Mass
cout << "Center of Mass of A:" << endl;
cout << a << ", " << b << "\n";
double traceA = A.Trace(); // calculate trace
cout << "Trace of A: " << traceA << endl;
}
catch (IndexOutOfBoundsException& ex) {
cout << "IndexOutOfBoundsException has been caught: ";
ex.print();
}
catch (Exception& ex) {
cout << "Exception has been caught: ";
ex.print();
}
catch (exception& ex) {
cout << "Standard exception has been caught: " << ex.what();
}
// char c;
// cin >> c;
return 0;
} }