diff --git a/include/tmatrix.h b/include/tmatrix.h index a1eaa2cf2..18e47bf50 100644 --- a/include/tmatrix.h +++ b/include/tmatrix.h @@ -27,6 +27,8 @@ class TDynamicVector { if (sz == 0) throw out_of_range("Vector size should be greater than zero"); + if (sz > MAX_VECTOR_SIZE) + throw out_of_range("Size exceeds the max allowed size"); pMem = new T[sz]();// {}; // У типа T д.б. констуктор по умолчанию } TDynamicVector(T* arr, size_t s) : sz(s) @@ -35,20 +37,39 @@ class TDynamicVector pMem = new T[sz]; std::copy(arr, arr + sz, pMem); } - TDynamicVector(const TDynamicVector& v) - { + TDynamicVector(const TDynamicVector& v) : sz(v.sz) { + pMem = new T[sz]; + std::copy(v.pMem, v.pMem + sz, pMem); } - TDynamicVector(TDynamicVector&& v) noexcept + TDynamicVector(TDynamicVector&& v) noexcept : sz(v.sz), pMem(v.pMem) { + v.sz = 0; + v.pMem = nullptr; } ~TDynamicVector() { + delete[] pMem; } TDynamicVector& operator=(const TDynamicVector& v) { + if (this == &v) + return *this; + if (v.sz == 0) + throw out_of_range("size should be greater than zero"); + TDynamicVector tmp(v); + swap(*this, tmp); + return *this; } TDynamicVector& operator=(TDynamicVector&& v) noexcept { + if (this == &v) + return *this; + delete[] pMem; + sz = v.sz; + pMem = v.pMem; + v.sz = 0; + v.pMem = nullptr; + return *this; } size_t size() const noexcept { return sz; } @@ -56,46 +77,91 @@ class TDynamicVector // индексация T& operator[](size_t ind) { + if (ind >= sz) + throw out_of_range("Index out of range"); + return pMem[ind]; } const T& operator[](size_t ind) const { + if (ind >= sz) + throw out_of_range("Index out of range"); + return pMem[ind]; } // индексация с контролем T& at(size_t ind) { + if (ind >= sz) + throw out_of_range("Index out of range"); + return pMem[ind]; } const T& at(size_t ind) const { + if (ind >= sz) + throw out_of_range("Index out of range"); + return pMem[ind]; } // сравнение bool operator==(const TDynamicVector& v) const noexcept { + return (sz == v.sz) && std::equal(pMem, pMem + sz, v.pMem); } bool operator!=(const TDynamicVector& v) const noexcept { + return !(*this == v); } // скалярные операции TDynamicVector operator+(T val) { + TDynamicVector result(*this); + for (size_t i = 0; i < sz; ++i) + result[i] += val; + return result; } TDynamicVector operator-(T val) { + TDynamicVector result(*this); + for (size_t i = 0; i < sz; ++i) + result[i] -= static_cast(val); + return result; } - TDynamicVector operator*(T val) + TDynamicVector operator*( T val) { + TDynamicVector result(*this); + for (size_t i = 0; i < sz; ++i) + result[i] *= static_cast(val); + return result; } // векторные операции TDynamicVector operator+(const TDynamicVector& v) { + if (sz != v.sz) + throw invalid_argument("Vectors must be the same size"); + TDynamicVector result(sz); + for (size_t i = 0; i < sz; ++i) + result[i] = pMem[i] + v.pMem[i]; + return result; } TDynamicVector operator-(const TDynamicVector& v) { + if (sz != v.sz) + throw invalid_argument("Vectors must be the same size"); + TDynamicVector result(sz); + for (size_t i = 0; i < sz; ++i) + result[i] = pMem[i] - v.pMem[i]; + return result; } - T operator*(const TDynamicVector& v) noexcept(noexcept(T())) + + int operator*(const TDynamicVector& v) noexcept(noexcept(T())) { + if (sz != v.sz) + throw invalid_argument("Vectors must be same size"); + int result = 0; + for (size_t i = 0; i < sz; ++i) + result += pMem[i] * v.pMem[i]; + return result; } friend void swap(TDynamicVector& lhs, TDynamicVector& rhs) noexcept @@ -129,45 +195,121 @@ class TDynamicMatrix : private TDynamicVector> using TDynamicVector>::sz; public: TDynamicMatrix(size_t s = 1) : TDynamicVector>(s) - { + { + if (s == 0) + throw out_of_range("size should be greater than zero"); + if (s > MAX_MATRIX_SIZE) + throw out_of_range("The matrix size is larger"); for (size_t i = 0; i < sz; i++) pMem[i] = TDynamicVector(sz); } + TDynamicMatrix& operator=(const TDynamicMatrix& m) + { + if (this == &m) + return *this; + if (m.sz == 0) + throw out_of_range("size should be greater than zero"); + for (size_t i = 0; i < sz; ++i) { + pMem[i] = TDynamicVector(); + } + if (sz != m.sz) { + delete[] pMem; + sz = m.sz; + pMem = new TDynamicVector[sz]; + } + for (size_t i = 0; i < sz; ++i) { + pMem[i] = m.pMem[i]; + } + return *this; + } + + TDynamicMatrix(const TDynamicMatrix& m) : TDynamicVector>(m.sz) { + for (size_t i = 0; i < sz; i++) { + pMem[i] = m.pMem[i]; + } + } using TDynamicVector>::operator[]; + using TDynamicVector>::size; // сравнение bool operator==(const TDynamicMatrix& m) const noexcept { + if (sz != m.sz) + return false; + for (size_t i = 0; i < sz; i++) { + if (pMem[i] != m.pMem[i]) + return false; + } + return true; } // матрично-скалярные операции - TDynamicMatrix operator*(const T& val) - { + TDynamicMatrix operator*(const T& val) const { + TDynamicMatrix result(sz); + for (size_t i = 0; i < sz; ++i) { + result[i] = pMem[i] * val; + } + return result; } // матрично-векторные операции - TDynamicVector operator*(const TDynamicVector& v) + TDynamicVector operator*(const TDynamicVector& v) const { + if (sz != v.size()) + throw invalid_argument("Matrix and vector sizes mismatch"); + TDynamicVectorresult(sz); + for (size_t i = 0; i < sz; ++i) + for (size_t j = 0; j < sz; ++j) + result[i] += (*this)[i][j] * v[i]; + return result; } // матрично-матричные операции TDynamicMatrix operator+(const TDynamicMatrix& m) { + if (sz != m.sz) + throw invalid_argument("Matrix sizes mismatch"); + TDynamicMatrix result(sz); + for (size_t i = 0; i < sz; ++i) + result[i] = (*this)[i] + m[i]; + return result; } TDynamicMatrix operator-(const TDynamicMatrix& m) { + if (sz != m.sz) + throw invalid_argument("Matrix sizes mismatch"); + TDynamicMatrix result(sz); + for (size_t i = 0; i < sz; ++i) + result[i] = (*this)[i] - m[i]; + return result; } - TDynamicMatrix operator*(const TDynamicMatrix& m) + TDynamicMatrix operator*(const TDynamicMatrix& m) const { + if (sz != m.sz) + throw invalid_argument("Matrix sizes mismatch"); + TDynamicMatrix result(sz); + for (size_t i = 0; i < sz; ++i) + for (size_t j = 0; j < sz; ++j) { + result[i][j] = T(); + for (size_t k = 0; k < sz; ++k) + result[i][j] += (*this)[i][k] * m[k][j]; + } + return result; } // ввод/вывод friend istream& operator>>(istream& istr, TDynamicMatrix& v) { + for (size_t i = 0; i < v.sz; ++i) + istr >> v.pMem[i]; + return istr; } friend ostream& operator<<(ostream& ostr, const TDynamicMatrix& v) { + for (size_t i = 0; i < v.sz; ++i) + ostr << v.pMem[i] << endl; + return ostr; } }; diff --git a/samples/sample_matrix.cpp b/samples/sample_matrix.cpp index d6bc73330..bdc26676a 100644 --- a/samples/sample_matrix.cpp +++ b/samples/sample_matrix.cpp @@ -28,3 +28,87 @@ void main() cout << "Matrix c = a + b" << endl << c << endl; } //--------------------------------------------------------------------------- + +using namespace std; + +int main() { + + + size_t n; + cout << "enter the matrix dimension "; + cin >> n; + + if (n == 0 || n > MAX_MATRIX_SIZE) { + throw out_of_range("the matrix size must be greater than 0 and not exceed the max"); + } + + try { + TDynamicMatrix a(n), b(n), c(n); + int i, j; + + for (i = 0; i < n; i++) { + for (j = i; j < n; j++) { + a[i][j] = i * 10 + j; + b[i][j] = (i * 10 + j) * 100; + } + } + + cout << "Matrix A:\n" << a << endl; + cout << "Matrix B:\n" << b << endl; + + c = a + b; + cout << "result of addition (A + B):\n" << c << endl; + + c = a - b; + cout << "result of subtraction (A - B):\n" << c << endl; + cout << "a == b? true - 1, false - 0" << endl << (a == b) << endl; + + int scalar = 5; + c = a * scalar; + + cout << "result of multiplication (A * " << scalar << "):\n" << c << endl; + + c = a * b; + cout << "result of matrix multiplication (A * B):\n" << c << endl; + + + TDynamicVector v(n); + TDynamicVector r(n); + for (size_t i = 0; i < v.size(); ++i) { + v[i] = 1; + } + + TDynamicVector result = a * v; + cout << "result of multiplying a matrix by a vector:\n" << result << endl; + + int k; + cout << "scalar?" << endl; + cin >> k; + r = result + k; + cout << "result of addition (vector + scalar) \n" << r << endl; + r = result - k; + cout << "result of subtraction (vector - scalar)\n" << r << endl; + r = result * k; + cout << "result of multiplication (vector * scalar)\n" << r << endl; + + TDynamicVector s = r; + cout << "true - 1, false - 0" << endl << (r == v) << endl << (s == r) << endl; + result = r + v; + cout << "result of addition (vector + vector) \n" << result << endl; + result = r - v; + cout << "result of subtraction (vector - vector) \n" << result << endl; + + + } + catch (const out_of_range& e) { + cout << "error: " << e.what() << endl; + } + catch (const invalid_argument& e) { + cout << "error: " << e.what() << endl; + } + catch (const exception& e) { + cout << "error: " << e.what() << endl; + } + + return 0; +} \ No newline at end of file diff --git a/test/test_tmatrix.cpp b/test/test_tmatrix.cpp index edaf75ef6..45f813920 100644 --- a/test/test_tmatrix.cpp +++ b/test/test_tmatrix.cpp @@ -4,108 +4,158 @@ TEST(TDynamicMatrix, can_create_matrix_with_positive_length) { - ASSERT_NO_THROW(TDynamicMatrix m(5)); + ASSERT_NO_THROW(TDynamicMatrix m(5)); } TEST(TDynamicMatrix, cant_create_too_large_matrix) { - ASSERT_ANY_THROW(TDynamicMatrix m(MAX_MATRIX_SIZE + 1)); + ASSERT_ANY_THROW(TDynamicMatrix m(MAX_MATRIX_SIZE + 1)); } TEST(TDynamicMatrix, throws_when_create_matrix_with_negative_length) { - ASSERT_ANY_THROW(TDynamicMatrix m(-5)); + ASSERT_ANY_THROW(TDynamicMatrix m(-5)); } TEST(TDynamicMatrix, can_create_copied_matrix) { - TDynamicMatrix m(5); + TDynamicMatrix m(5); - ASSERT_NO_THROW(TDynamicMatrix m1(m)); + ASSERT_NO_THROW(TDynamicMatrix m1(m)); } TEST(TDynamicMatrix, copied_matrix_is_equal_to_source_one) { - ADD_FAILURE(); + TDynamicMatrix mat1(3); + mat1[0][0] = 1; mat1[0][1] = 2; mat1[0][2] = 3; + mat1[1][0] = 4; mat1[1][1] = 5; mat1[1][2] = 6; + mat1[2][0] = 7; mat1[2][1] = 8; mat1[2][2] = 9; + + TDynamicMatrix mat2 = mat1; + EXPECT_TRUE(mat1 == mat2); } TEST(TDynamicMatrix, copied_matrix_has_its_own_memory) { - ADD_FAILURE(); + TDynamicMatrix m(3); + m[0][0] = 1; + m[1][0] = 2; + m[2][0] = 3; + TDynamicMatrix m_copy = m; + m[0][0] = 10; + EXPECT_NE(&m[0][0], &m_copy[0][0]); } TEST(TDynamicMatrix, can_get_size) { - ADD_FAILURE(); + TDynamicMatrix m(3); + EXPECT_EQ(m.size(), 3); } TEST(TDynamicMatrix, can_set_and_get_element) { - ADD_FAILURE(); + TDynamicMatrix m(3); + m[0][0] = 42; + EXPECT_EQ(m[0][0], 42); } TEST(TDynamicMatrix, throws_when_set_element_with_negative_index) { - ADD_FAILURE(); + TDynamicMatrix m(3); + ASSERT_ANY_THROW(m[-1][0] = 10); + } TEST(TDynamicMatrix, throws_when_set_element_with_too_large_index) { - ADD_FAILURE(); + TDynamicMatrix m(3); + ASSERT_ANY_THROW(m[5][0] = 10); } TEST(TDynamicMatrix, can_assign_matrix_to_itself) { - ADD_FAILURE(); + TDynamicMatrix m(3); + m[0][0] = 10; + ASSERT_NO_THROW(m = m); } TEST(TDynamicMatrix, can_assign_matrices_of_equal_size) { - ADD_FAILURE(); + TDynamicMatrix m1(3); + TDynamicMatrix m2(3); + m1[0][0] = 1; + m2 = m1; + EXPECT_TRUE(m1 == m2); } TEST(TDynamicMatrix, assign_operator_change_matrix_size) { - ADD_FAILURE(); + TDynamicMatrix m1(3); + TDynamicMatrix m2(5); + m1 = m2; + EXPECT_EQ(m1.size(), 5); } TEST(TDynamicMatrix, can_assign_matrices_of_different_size) { - ADD_FAILURE(); + TDynamicMatrix m1(3); + TDynamicMatrix m2(5); + ASSERT_NO_THROW(m1 = m2); } TEST(TDynamicMatrix, compare_equal_matrices_return_true) { - ADD_FAILURE(); + TDynamicMatrix m1(3); + TDynamicMatrix m2(3); + m1[0][0] = 1; + m2[0][0] = 1; + EXPECT_TRUE(m1 == m2); } TEST(TDynamicMatrix, compare_matrix_with_itself_return_true) { - ADD_FAILURE(); + TDynamicMatrix m(3); + EXPECT_TRUE(m == m); } TEST(TDynamicMatrix, matrices_with_different_size_are_not_equal) { - ADD_FAILURE(); + TDynamicMatrix m1(3); + TDynamicMatrix m2(5); + EXPECT_FALSE(m1 == m2); } TEST(TDynamicMatrix, can_add_matrices_with_equal_size) { - ADD_FAILURE(); + TDynamicMatrix m1(3); + TDynamicMatrix m2(3); + m1[0][0] = 1; + m2[0][0] = 2; + TDynamicMatrix m3 = m1 + m2; + EXPECT_EQ(m3[0][0], 3); } TEST(TDynamicMatrix, cant_add_matrices_with_not_equal_size) { - ADD_FAILURE(); + TDynamicMatrix m1(3); + TDynamicMatrix m2(4); + ASSERT_ANY_THROW(m1 + m2); + } TEST(TDynamicMatrix, can_subtract_matrices_with_equal_size) { - ADD_FAILURE(); + TDynamicMatrix m1(3); + TDynamicMatrix m2(3); + m1[0][0] = 3; + m2[0][0] = 2; + TDynamicMatrix m3 = m1 - m2; + EXPECT_EQ(m3[0][0], 1); } TEST(TDynamicMatrix, cant_subtract_matrixes_with_not_equal_size) { - ADD_FAILURE(); -} - + TDynamicMatrix m1(3); + TDynamicMatrix m2(4); + ASSERT_ANY_THROW(m1 - m2); +} \ No newline at end of file diff --git a/test/test_tvector.cpp b/test/test_tvector.cpp index 1f7737755..d2af25d35 100644 --- a/test/test_tvector.cpp +++ b/test/test_tvector.cpp @@ -26,12 +26,21 @@ TEST(TDynamicVector, can_create_copied_vector) TEST(TDynamicVector, copied_vector_is_equal_to_source_one) { - ADD_FAILURE(); + TDynamicVector v(5); + for (size_t i = 0; i < v.size(); ++i) { + v[i] = static_cast(i); + } + TDynamicVector v1(v); + EXPECT_EQ(v, v1); } TEST(TDynamicVector, copied_vector_has_its_own_memory) { - ADD_FAILURE(); + TDynamicVector v(3); + v[0] = 10; + TDynamicVector v1(v); + v1[0] = 20; + EXPECT_NE(v[0], v1[0]); } TEST(TDynamicVector, can_get_size) @@ -51,91 +60,161 @@ TEST(TDynamicVector, can_get_size) TEST(TDynamicVector, throws_when_set_element_with_negative_index) { - ADD_FAILURE(); + TDynamicVector v(3); + ASSERT_ANY_THROW(v.at(-1) = 10); } TEST(TDynamicVector, throws_when_set_element_with_too_large_index) { - ADD_FAILURE(); + TDynamicVector v(3); + ASSERT_ANY_THROW(v.at(3) = 50); } TEST(TDynamicVector, can_assign_vector_to_itself) { - ADD_FAILURE(); + TDynamicVector v(3); + for (size_t i = 0; i < v.size(); ++i) { + v[i] = static_cast(i); + } + ASSERT_NO_THROW(v = v); + EXPECT_EQ(v, v); } TEST(TDynamicVector, can_assign_vectors_of_equal_size) { - ADD_FAILURE(); + TDynamicVector v1(5); + TDynamicVector v2(5); + for (size_t i = 0; i < v1.size(); ++i) { + v1[i] = static_cast(i); + } + ASSERT_NO_THROW(v2 = v1); + EXPECT_EQ(v1, v2); } TEST(TDynamicVector, assign_operator_change_vector_size) { - ADD_FAILURE(); + TDynamicVector v1(5); + TDynamicVector v2(10); + v2 = v1; + EXPECT_EQ(v1.size(), v2.size()); } TEST(TDynamicVector, can_assign_vectors_of_different_size) { - ADD_FAILURE(); + TDynamicVector v1(5); + TDynamicVector v2(10); + for (size_t i = 0; i < v1.size(); ++i) { + v1[i] = static_cast(i); + } + ASSERT_NO_THROW(v2 = v1); + EXPECT_EQ(v1, v2); } TEST(TDynamicVector, compare_equal_vectors_return_true) { - ADD_FAILURE(); + TDynamicVector v1(5), v2(5); + for (size_t i = 0; i < v1.size(); ++i) + v1[i] = v2[i] = static_cast(i); + EXPECT_TRUE(v1 == v2); } TEST(TDynamicVector, compare_vector_with_itself_return_true) { - ADD_FAILURE(); + TDynamicVector v(5); + EXPECT_TRUE(v == v); } TEST(TDynamicVector, vectors_with_different_size_are_not_equal) { - ADD_FAILURE(); + TDynamicVector v(5), v2(10); + EXPECT_FALSE(v == v2); } TEST(TDynamicVector, can_add_scalar_to_vector) { - ADD_FAILURE(); + TDynamicVector v(3); + for (size_t i = 0; i < v.size(); ++i) + v[i] = static_cast(i); + TDynamicVector res = v + 5; + EXPECT_EQ(5, res[0]); + EXPECT_EQ(6, res[1]); + EXPECT_EQ(7, res[2]); } TEST(TDynamicVector, can_subtract_scalar_from_vector) { - ADD_FAILURE(); + TDynamicVector v(3); + for (size_t i = 0; i < v.size(); ++i) + v[i] = static_cast(i); + TDynamicVector res = v - 1; + EXPECT_EQ(-1, res[0]); + EXPECT_EQ(0, res[1]); + EXPECT_EQ(1, res[2]); } TEST(TDynamicVector, can_multiply_scalar_by_vector) { - ADD_FAILURE(); + TDynamicVector v(3); + for (size_t i = 0; i < v.size(); ++i) + v[i] = static_cast(i); + TDynamicVector res = v * 2; + EXPECT_EQ(0, res[0]); + EXPECT_EQ(2, res[1]); + EXPECT_EQ(4, res[2]); } TEST(TDynamicVector, can_add_vectors_with_equal_size) { - ADD_FAILURE(); + TDynamicVector v1(3), v2(3); + for (size_t i = 0; i < v1.size(); ++i) { + v1[i] = static_cast(i); + v2[i] = static_cast(i * 2); + } + TDynamicVector res = v1 + v2; + EXPECT_EQ(0, res[0]); + EXPECT_EQ(3, res[1]); + EXPECT_EQ(6, res[2]); } TEST(TDynamicVector, cant_add_vectors_with_not_equal_size) { - ADD_FAILURE(); + TDynamicVector v1(3), v2(5); + ASSERT_ANY_THROW(v1 + v2); } TEST(TDynamicVector, can_subtract_vectors_with_equal_size) { - ADD_FAILURE(); + TDynamicVector v1(3), v2(3); + for (size_t i = 0; i < v1.size(); ++i) { + v1[i] = static_cast(i * 3); + v2[i] = static_cast(i); + } + TDynamicVector res = v1 - v2; + EXPECT_EQ(0, res[0]); + EXPECT_EQ(2, res[1]); + EXPECT_EQ(4, res[2]); } TEST(TDynamicVector, cant_subtract_vectors_with_not_equal_size) { - ADD_FAILURE(); + TDynamicVector v1(3), v2(5); + ASSERT_ANY_THROW(v1 - v2); } TEST(TDynamicVector, can_multiply_vectors_with_equal_size) { - ADD_FAILURE(); + TDynamicVector v1(3), v2(3); + for (size_t i = 0; i < v1.size(); ++i) { + v1[i] = static_cast(i + 1); + v2[i] = static_cast(i + 2); + } + int res = v1 * v2; + EXPECT_EQ(20, res); } TEST(TDynamicVector, cant_multiply_vectors_with_not_equal_size) { - ADD_FAILURE(); + TDynamicVector v1(3), v2(5); + ASSERT_ANY_THROW(v1 * v2); }