Загрузка данных
#include <iostream>
#include <stdexcept>
#include <utility>
using namespace std;
class Matrix;
// ======================================================
// VECTOR
// ======================================================
class Vector {
protected:
int size;
int* data;
public:
// Конструктор по умолчанию
Vector()
: size(0), data(nullptr)
{
}
// Конструктор с параметром
Vector(int size)
: size(size),
data(size > 0 ? new int[size]{} : nullptr)
{
if (size < 0)
throw invalid_argument("Vector size cannot be negative");
}
// Копирующий конструктор
Vector(const Vector& other)
: size(other.size),
data(other.size > 0 ? new int[other.size] : nullptr)
{
for (int i = 0; i < size; i++)
data[i] = other.data[i];
}
// Перемещающий конструктор
Vector(Vector&& other) noexcept
: size(other.size),
data(other.data)
{
other.size = 0;
other.data = nullptr;
}
// Деструктор
virtual ~Vector()
{
delete[] data;
}
// Копирующее присваивание
Vector& operator=(const Vector& other)
{
if (this == &other)
return *this;
int* newData = nullptr;
if (other.size > 0)
newData = new int[other.size];
for (int i = 0; i < other.size; i++)
newData[i] = other.data[i];
delete[] data;
data = newData;
size = other.size;
return *this;
}
// Перемещающее присваивание
Vector& operator=(Vector&& other) noexcept
{
if (this == &other)
return *this;
delete[] data;
data = other.data;
size = other.size;
other.data = nullptr;
other.size = 0;
return *this;
}
int getSize() const
{
return size;
}
// Доступ []
int& operator[](int i)
{
if (i < 0 || i >= size)
throw out_of_range("Vector index out of range");
return data[i];
}
const int& operator[](int i) const
{
if (i < 0 || i >= size)
throw out_of_range("Vector index out of range");
return data[i];
}
// Vector + Vector
Vector operator+(const Vector& other) const
{
if (size != other.size)
throw invalid_argument("Vectors have different sizes");
Vector result(size);
for (int i = 0; i < size; i++)
result[i] = data[i] + other[i];
return result;
}
// Vector - Vector
Vector operator-(const Vector& other) const
{
if (size != other.size)
throw invalid_argument("Vectors have different sizes");
Vector result(size);
for (int i = 0; i < size; i++)
result[i] = data[i] - other[i];
return result;
}
// +=
Vector& operator+=(const Vector& other)
{
if (size != other.size)
throw invalid_argument("Vectors have different sizes");
for (int i = 0; i < size; i++)
data[i] += other[i];
return *this;
}
// -=
Vector& operator-=(const Vector& other)
{
if (size != other.size)
throw invalid_argument("Vectors have different sizes");
for (int i = 0; i < size; i++)
data[i] -= other[i];
return *this;
}
// Vector * число
Vector operator*(int k) const
{
Vector result(size);
for (int i = 0; i < size; i++)
result[i] = data[i] * k;
return result;
}
// *= число
Vector& operator*=(int k)
{
for (int i = 0; i < size; i++)
data[i] *= k;
return *this;
}
// <<
friend ostream& operator<<(ostream& out, const Vector& v)
{
out << "[ ";
for (int i = 0; i < v.size; i++)
out << v.data[i] << " ";
out << "]";
return out;
}
};
// ======================================================
// MATRIX
// ======================================================
class Matrix : public Vector {
private:
int rows;
int cols;
public:
// Конструктор по умолчанию
Matrix()
: Vector(),
rows(0),
cols(0)
{
}
// Конструктор с параметрами
Matrix(int rows, int cols)
: Vector(rows * cols),
rows(rows),
cols(cols)
{
if (rows < 0 || cols < 0)
throw invalid_argument("Matrix sizes cannot be negative");
}
// Копирующий конструктор
Matrix(const Matrix& other)
: Vector(other),
rows(other.rows),
cols(other.cols)
{
}
// Перемещающий конструктор
Matrix(Matrix&& other) noexcept
: Vector(std::move(other)),
rows(other.rows),
cols(other.cols)
{
other.rows = 0;
other.cols = 0;
}
// Деструктор
~Matrix() override = default;
// Копирующее присваивание
Matrix& operator=(const Matrix& other)
{
if (this == &other)
return *this;
Vector::operator=(other);
rows = other.rows;
cols = other.cols;
return *this;
}
// Перемещающее присваивание
Matrix& operator=(Matrix&& other) noexcept
{
if (this == &other)
return *this;
Vector::operator=(std::move(other));
rows = other.rows;
cols = other.cols;
other.rows = 0;
other.cols = 0;
return *this;
}
int getRows() const
{
return rows;
}
int getCols() const
{
return cols;
}
// ==================================================
// m[row][col]
// ==================================================
int* operator[](int row)
{
if (row < 0 || row >= rows)
throw out_of_range("Matrix row out of range");
return data + row * cols;
}
const int* operator[](int row) const
{
if (row < 0 || row >= rows)
throw out_of_range("Matrix row out of range");
return data + row * cols;
}
// Matrix + Matrix
Matrix operator+(const Matrix& other) const
{
if (rows != other.rows || cols != other.cols)
throw invalid_argument("Matrices have different sizes");
Matrix result(rows, cols);
for (int i = 0; i < size; i++)
result.data[i] = data[i] + other.data[i];
return result;
}
// Matrix - Matrix
Matrix operator-(const Matrix& other) const
{
if (rows != other.rows || cols != other.cols)
throw invalid_argument("Matrices have different sizes");
Matrix result(rows, cols);
for (int i = 0; i < size; i++)
result.data[i] = data[i] - other.data[i];
return result;
}
// Matrix * Matrix
Matrix operator*(const Matrix& other) const
{
if (cols != other.rows)
throw invalid_argument("Matrices cannot be multiplied");
Matrix result(rows, other.cols);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < other.cols; j++)
{
for (int k = 0; k < cols; k++)
{
result[i][j] +=
(*this)[i][k] * other[k][j];
}
}
}
return result;
}
// +=
Matrix& operator+=(const Matrix& other)
{
*this = *this + other;
return *this;
}
// -=
Matrix& operator-=(const Matrix& other)
{
*this = *this - other;
return *this;
}
// *= Matrix
Matrix& operator*=(const Matrix& other)
{
*this = *this * other;
return *this;
}
// Matrix * число
Matrix operator*(int k) const
{
Matrix result(*this);
for (int i = 0; i < result.size; i++)
result.data[i] *= k;
return result;
}
// *= число
Matrix& operator*=(int k)
{
for (int i = 0; i < size; i++)
data[i] *= k;
return *this;
}
// <<
friend ostream& operator<<(ostream& out, const Matrix& m)
{
for (int i = 0; i < m.rows; i++)
{
for (int j = 0; j < m.cols; j++)
out << m[i][j] << " ";
out << '\n';
}
return out;
}
};
// ======================================================
// VECTOR * VECTOR
// ======================================================
// Скалярное произведение
long long operator*(const Vector& a, const Vector& b)
{
if (a.getSize() != b.getSize())
throw invalid_argument("Vectors have different sizes");
long long result = 0;
for (int i = 0; i < a.getSize(); i++)
result += 1LL * a[i] * b[i];
return result;
}
// ======================================================
// MATRIX * VECTOR
// ======================================================
Vector operator*(const Matrix& m, const Vector& v)
{
if (m.getCols() != v.getSize())
throw invalid_argument(
"Matrix and vector cannot be multiplied"
);
Vector result(m.getRows());
for (int i = 0; i < m.getRows(); i++)
{
for (int j = 0; j < m.getCols(); j++)
{
result[i] += m[i][j] * v[j];
}
}
return result;
}
// ======================================================
// VECTOR * MATRIX
// ======================================================
Vector operator*(const Vector& v, const Matrix& m)
{
if (v.getSize() != m.getRows())
throw invalid_argument(
"Vector and matrix cannot be multiplied"
);
Vector result(m.getCols());
for (int j = 0; j < m.getCols(); j++)
{
for (int i = 0; i < m.getRows(); i++)
{
result[j] += v[i] * m[i][j];
}
}
return result;
}
// ======================================================
// NUMBER * VECTOR
// ======================================================
Vector operator*(int k, const Vector& v)
{
return v * k;
}
// ======================================================
// NUMBER * MATRIX
// ======================================================
Matrix operator*(int k, const Matrix& m)
{
return m * k;
}
// ======================================================
// ПРОВЕРКА ВОЗМОЖНОСТИ СЛОЖЕНИЯ
// ======================================================
// Vector + Vector
bool canAdd(const Vector& a, const Vector& b)
{
return a.getSize() == b.getSize();
}
// Vector + Matrix
bool canAdd(const Vector&, const Matrix&)
{
return false;
}
// Matrix + Vector
bool canAdd(const Matrix&, const Vector&)
{
return false;
}
// Matrix + Matrix
bool canAdd(const Matrix& a, const Matrix& b)
{
return
a.getRows() == b.getRows()
&&
a.getCols() == b.getCols();
}
// ======================================================
// ПРОВЕРКА ВОЗМОЖНОСТИ УМНОЖЕНИЯ
// ======================================================
// Vector * Vector
bool canMultiply(const Vector& a, const Vector& b)
{
return a.getSize() == b.getSize();
}
// Vector * Matrix
bool canMultiply(const Vector& v, const Matrix& m)
{
return v.getSize() == m.getRows();
}
// Matrix * Vector
bool canMultiply(const Matrix& m, const Vector& v)
{
return m.getCols() == v.getSize();
}
// Matrix * Matrix
bool canMultiply(const Matrix& a, const Matrix& b)
{
return a.getCols() == b.getRows();
}
// ======================================================
// MAIN
// ======================================================
int main()
{
try
{
// ==============================================
// ВЕКТОРЫ
// ==============================================
Vector v1(3);
v1[0] = 1;
v1[1] = 2;
v1[2] = 3;
Vector v2(3);
v2[0] = 4;
v2[1] = 5;
v2[2] = 6;
cout << "v1 = " << v1 << '\n';
cout << "v2 = " << v2 << '\n';
cout << "v1 + v2 = "
<< v1 + v2 << '\n';
cout << "v1 - v2 = "
<< v1 - v2 << '\n';
cout << "v1 * v2 = "
<< v1 * v2 << '\n';
cout << "v1 * 3 = "
<< v1 * 3 << '\n';
cout << '\n';
// ==============================================
// МАТРИЦА A 2x3
// ==============================================
Matrix a(2, 3);
a[0][0] = 1;
a[0][1] = 2;
a[0][2] = 3;
a[1][0] = 4;
a[1][1] = 5;
a[1][2] = 6;
// ==============================================
// МАТРИЦА B 3x2
// ==============================================
Matrix b(3, 2);
b[0][0] = 1;
b[0][1] = 2;
b[1][0] = 3;
b[1][1] = 4;
b[2][0] = 5;
b[2][1] = 6;
cout << "A:\n";
cout << a << '\n';
cout << "B:\n";
cout << b << '\n';
// Matrix * Matrix
cout << "A * B:\n";
cout << a * b << '\n';
// ==============================================
// MATRIX * VECTOR
// ==============================================
Vector x(3);
x[0] = 1;
x[1] = 2;
x[2] = 3;
cout << "A * x = "
<< a * x << '\n';
// ==============================================
// VECTOR * MATRIX
// ==============================================
Vector y(2);
y[0] = 10;
y[1] = 20;
cout << "y * A = "
<< y * a << '\n';
// ==============================================
// КОПИРОВАНИЕ
// ==============================================
Matrix c = a;
cout << "\nCopy of A:\n";
cout << c;
// ==============================================
// ПЕРЕМЕЩЕНИЕ
// ==============================================
Matrix moved = std::move(c);
cout << "\nMoved matrix:\n";
cout << moved;
// ==============================================
// ПРОВЕРКИ
// ==============================================
cout << boolalpha;
cout << "\nCan add v1 and v2: "
<< canAdd(v1, v2) << '\n';
cout << "Can add v1 and A: "
<< canAdd(v1, a) << '\n';
cout << "Can multiply A and B: "
<< canMultiply(a, b) << '\n';
cout << "Can multiply A and x: "
<< canMultiply(a, x) << '\n';
}
catch (const exception& e)
{
cout << "Error: "
<< e.what() << '\n';
}
return 0;
}