Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
1 / 1 / 0
Регистрация: 11.10.2021
Сообщений: 11
1

Создать класс Array

13.11.2021, 14:32. Показов 896. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. Помогите, пожалуйста, с заданием:
Создать класс Array, в котором перегрузить операторы:
а) «&» для перемножения двух матриц;
б) «+» для сложения двух матриц.
Память под матрицы выделять динамически. Реализовать
конструкторы (по умолчанию, с параметрами, копирования), деструкторы.
Реализовать friend-функции для операторов ввода/вывода в поток.
Реализовал все операции с матрицами, но как осуществить перегрузку операторов и как нужно здесь использовать классы? Стоит ли разбивать все на отдельные функции?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <iostream>
using namespace std;
 
int main()
{
    int row1, row2, col1, col2;
    double** a, ** b, ** c, **d;
    system("chcp 1251");
    system("cls");
    cout << "Введите количество строк первой матрицы: ";
    cin >> row1;
    cout << "Введите количество столбцов первой матрицы: ";
    cin >> col1;
    cout << "Введите количество строк второй матрицы: ";
    cin >> row2;
    cout << "Введите количество столбцов второй матрицы: ";
    cin >> col2;
    if (col1 != row2) {
        cout << "Умножение невозможно!";
        cin.get(); cin.get();
        return 0;
    }
    // Ввод элементов первой матрицы
    a = new double* [row1];
    cout << "Введите элементы первой матрицы" << endl;
    for (int i = 0; i < row1; i++)
    {
        a[i] = new double[col1];
        for (int j = 0; j < col1; j++)
        {
            cout << "a[" << i << "][" << j << "]= ";
            cin >> a[i][j];
        }
    }
    // Вывод элементов первой матрицы
    for (int i = 0; i < row1; i++)
    {
        for (int j = 0; j < col1; j++)
            cout << a[i][j] << " ";
        cout << endl;
    }
    // Ввод элементов второй матрицы
    b = new double* [row2];
    cout << "Введите элементы второй матрицы" << endl;
    for (int i = 0; i < row2; i++)
    {
        b[i] = new double[col2];
        for (int j = 0; j < col2; j++)
        {
            cout << "b[" << i << "][" << j << "]= ";
            cin >> b[i][j];
        }
    }
    // Вывод элементов второй матрицы
    for (int i = 0; i < row2; i++)
    {
        for (int j = 0; j < col2; j++)
        {
            cout << b[i][j] << " ";
        }
        cout << endl;
    }
    // Сложение матриц
    c = new double* [row1];
    for (int i = 0; i < row1; i++)
    {
        c[i] = new double[row2];
        for (int j = 0; j < row2; j++)
                c[i][j] = a[i][j] + b[i][j];
    }
    // Вывод матрицы сложения
    cout << "Матрица сложения" << endl;
    for (int i = 0; i < row1; i++)
    {
        for (int j = 0; j < col2; j++)
            cout << c[i][j] << " ";
        cout << endl;
    }
    cin.get(); cin.get();
 
    // Умножение матриц
    d = new double* [row1];
    for (int i = 0; i < row1; i++)
    {
        d[i] = new double[col2];
        for (int j = 0; j < col2; j++)
        {
            d[i][j] = 0;
            for (int k = 0; k < col1; k++)
                d[i][j] += a[i][k] * b[k][j];
        }
    }
    // Вывод матрицы произведения
    cout << "Матрица произведения" << endl;
    for (int i = 0; i < row1; i++)
    {
        for (int j = 0; j < col2; j++)
            cout << d[i][j] << " ";
        cout << endl;
    }
    cin.get(); cin.get();
    return 0;
}
Пожалуйста!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.11.2021, 14:32
Ответы с готовыми решениями:

Создать базовый класс - Array и производный класс - Money для работы денежной суммы
ПОМОГИТЕ, ПОЖАЛУЙСТА, С ЗАДАЧЕЙ Создать базовый класс - Array и производный класс - Money для...

Создать базовый класс Array
Задание выглядит так: Создать базовый класс Array, в котором определите полемассив подходящеrо...

Создать базовый класс Array
Создать базовый класс Array, в котором определите поле-массив подходящего типа и поле для хранения...

Создать базовый класс Array
Создать базовый класс Array, в котором определите поле-массив подходящего типа и поле для хранения...

5
4773 / 2582 / 894
Регистрация: 29.11.2010
Сообщений: 5,590
14.11.2021, 04:16 2
Цитата Сообщение от vell1 Посмотреть сообщение
как осуществить перегрузку операторов
Тут вам без классов не обойтись.

Цитата Сообщение от vell1 Посмотреть сообщение
Создать класс Array, в котором перегрузить операторы
Под термином Array обычно понимают одномерные массивы
Цитата Сообщение от vell1 Посмотреть сообщение
а) «&» для перемножения двух матриц;
б) «+» для сложения двух матриц.
Но дальше используется термин "матрицы", под которым обычно понимаются 2+ мерные массивы.

Это ошибка? Опечатка?

Добавлено через 11 минут
Этот код делает примерно то же самое, что и ваш, но с классами и операторами.
(сработает ТОЛЬКО если ввести две квадратные матрицы одинакового размера, иначе -- эксепшон).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
#include <iostream>
#include <istream>
#include <ostream>
#include <utility>
#include <iomanip>
 
template<typename T>
class Matrix {
public:
    // правило трёх:
    // конструктор
    Matrix(std::size_t height, std::size_t width): height(height), width(width), data(construct(height, width)) {}
    // конструктор копирования
    Matrix(const Matrix<T> &other): height(other.height), width(other.width), data(copy(construct(height, width), other.data, height, width)) {}
    // оператор присваивания
    Matrix<T> &operator=(const Matrix<T> &other) {
        if (this != &other) {
            data = destruct(data, height, width);
            this->height = other.height;
            this->width = other.width;
            this->data = copy(construct(height, width), other.data, height, width);
        }
        return *this;
    }
    // правило пяти:
    // move-конструктор
    Matrix(Matrix<T> &&other) noexcept: height(std::exchange(other.height, 0)), width(std::exchange(other.width, 0)), data(std::exchange(other.data, nullptr)) {}
    // move-оператор присваивания
    Matrix<T> &operator=(Matrix<T> &&other) noexcept {
        if (this != &other) {
            this->height = std::exchange(other.height, 0);
            this->width = std::exchange(other.width, 0);
            this->data = std::exchange(other.data, nullptr);
        }
        return *this;
    }
    virtual ~Matrix() {
        data = destruct(data, height);
    }
 
    // конструктор с генерацией значений
    template<typename Generator>
    Matrix(std::size_t height, std::size_t width, Generator g): height(height), width(width), data(generate(construct(height, width), height, width, g)) {}
 
    // оператор доступа к элементам матрицы
    T *operator[](std::size_t row) {
        return data[row];
    }
 
    // оператор доступа к элементам матрицы
    const T *operator[](std::size_t row) const {
        return data[row];
    }
 
    // оператор доступа к элементам матрицы
    T &operator()(std::size_t row, std::size_t col) {
        return data[row][col];
    }
    // константный оператор доступа к константным элементам матрицы
    const T &operator()(std::size_t row, std::size_t col) const {
        return data[row][col];
    }
    // количество строк
    std::size_t getHeight() const {
        return height;
    }
    // количество столбцов
    std::size_t getWidth() const {
        return width;
    }
private:
    template<typename Generator>
    static T **generate(T **data, std::size_t height, std::size_t width, Generator g) {
        for (std::size_t i = 0; i < height; ++i) {
            for (std::size_t j = 0; j < width; ++j) {
                data[i][j] = g();
            }
        }
        return data;
    }
    static T **construct(std::size_t height, std::size_t width) {
        T **result = new T*[height];
        for (std::size_t i = 0; i < height; ++i) {
            result[i] = new T[width]{0};
        }
        return result;
    }
    static T **copy(T **destination, T **source, std::size_t height, std::size_t width) {
        for (std::size_t i = 0; i < height; ++i) {
            for (std::size_t j = 0; j < width; ++j) {
                destination[i][j] = source[i][j];
            }
        }
        return destination;
    }
    static T **destruct(T **data, std::size_t height) {
        if (data != nullptr) {
            for (std::size_t i = 0; i < height; ++i) {
                delete [] data[i];
            }
            delete [] data;
        }
        return nullptr;
    }
    std::size_t height;
    std::size_t width;
    T **data;
};
 
template<typename T>
Matrix<T> operator+(const Matrix<T> &a, const Matrix<T> &b) {
    if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) {
        throw std::invalid_argument("matrices should be of the same dimension sizes");
    }
    Matrix<T> result(a.getHeight(), a.getWidth());
    for (std::size_t i = 0; i < a.getHeight(); ++i) {
        for (std::size_t j = 0; j < a.getWidth(); ++j) {
            result(i, j) = a(i, j) + b(i, j);
        }
    }
    return result;
}
 
template<typename T>
Matrix<T> operator-(const Matrix<T> &a, const Matrix<T> &b) {
    if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) {
        throw std::invalid_argument("matrices should be of the same dimension sizes");
    }
    Matrix<T> result(a.getHeight(), a.getWidth());
    for (std::size_t i = 0; i < a.getHeight(); ++i) {
        for (std::size_t j = 0; j < a.getWidth(); ++j) {
            result(i, j) = a(i, j) + b(i, j);
        }
    }
    return result;
}
 
template<typename T>
Matrix<T> operator*(const Matrix<T> &a, const Matrix<T> &b) {
    if (a.getWidth() != b.getHeight()) {
        throw std::invalid_argument("matrix a should have it's width equal to matrix b height");
    }
    Matrix<T> result(a.getHeight(), b.getWidth());
    for (std::size_t i = 0; i < result.getHeight(); ++i) {
        for (std::size_t j = 0; j < result.getWidth(); ++j) {
            result(i, j) = 0;
            for (std::size_t k = 0; k < a.getWidth(); ++k) {
                result(i, j) += a(i, k) * b(k, j);
            }
        }
    }
    return result;
}
 
template<typename T>
Matrix<T> operator*(const Matrix<T> &a, const T &scalar) {
    Matrix<T> result(a.getHeight(), a.getWidth());
    for (std::size_t i = 0; i < result.getHeight(); ++i) {
        for (std::size_t j = 0; j < result.getWidth(); ++j) {
            result(i, j) = a(i, j) * scalar;
        }
    }
    return result;
}
 
template<typename T>
Matrix<T> operator/(const Matrix<T> &a, const T &scalar) {
    Matrix<T> result(a.getHeight(), a.getWidth());
    for (std::size_t i = 0; i < result.getHeight(); ++i) {
        for (std::size_t j = 0; j < result.getWidth(); ++j) {
            result(i, j) = a(i, j) / scalar;
        }
    }
    return result;
}
 
template<typename T>
Matrix<T> transpose(const Matrix<T> &m) {
    Matrix<T> result(m.getWidth(), m.getHeight());
    for (std::size_t i = 0; i < result.getHeight(); ++i) {
        for (std::size_t j = 0; j < result.getWidth(); ++j) {
            result(i, j) = m(j, i);
        }
    }
    return result;
}
 
template<typename T, typename Comparator>
T find_max(const Matrix<T> &m, Comparator comare) {
    T value = m(0, 0);
    for (std::size_t i = 0; i < m.getHeight(); ++i) {
        for (std::size_t j = 0; j < m.getWidth(); ++j) {
            if (comare(m(i, j), value)) {
                value = m(i, j);
            }
        }
    }
    return value;
}
 
 
template<typename T>
Matrix<T> identity(std::size_t size) {
    Matrix<T> result(size, size);
    for (std::size_t i = 0; i < size; ++i) {
        result(i, i) = 1;
    }
    return result;
}
 
// оператор вывода матрицы на экран
template<typename T>
std::ostream &operator<<(std::ostream &out, const Matrix<T> &m) {
    for (std::size_t i = 0; i < m.getHeight(); ++i) {
        for (std::size_t j = 0; j < m.getWidth(); ++j) {
            out << std::fixed << std::setprecision(2) << std::setw(7) << m(i, j);
        }
        out << std::endl;
    }
    return out;
}
 
// оператор ввода матрицы из потока
template<typename T>
std::istream &operator>>(std::istream &in, Matrix<T> &m) {
    for (std::size_t i = 0; i < m.getHeight(); ++i) {
        for (std::size_t j = 0; j < m.getWidth(); ++j) {
            in >> m(i, j);
        }
    }
    return in;
}
 
 
int main() {
    std::size_t height_a, height_b, width_a, width_b;
 
    std::cout << "Input first matrix height: ";
    std::cin >> height_a;
    std::cout << "Input first matrix width: ";
    std::cin >> width_a;
    std::cout << "Input second matrix height: ";
    std::cin >> height_b;
    std::cout << "Input second matrix width: ";
    std::cin >> width_b;
 
    if (width_a != height_b) {
        std::cout << "Impossible to multiply those two" << std::endl;
        return 0;
    }
 
    Matrix<double> a(height_a, width_a);
    std::cin >> a;
    Matrix<double> b(height_b, width_b);
    std::cin >> b;
 
    std::cout << "a = " << std::endl << a << std::endl << "b = " << std::endl << b << std::endl;
    std::cout << "a + b = " << std::endl << (a + b) << std::endl;
    std::cout << "a * b = " << std::endl << (a * b) << std::endl;
 
}
В коде много ненужного вам, лень было вырезать, думаю, основную идею передает.
2
1 / 1 / 0
Регистрация: 11.10.2021
Сообщений: 11
14.11.2021, 11:11  [ТС] 3
Спасибо!
Да, там ошибка, должны фигурировать только матрицы
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// move-конструктор
    Matrix(Matrix<T>&& other) noexcept : height(std::exchange(other.height, 0)), width(std::exchange(other.width, 0)), data(std::exchange(other.data, nullptr)) {}
    // move-оператор присваивания
    Matrix<T>& operator=(Matrix<T>&& other) noexcept {
        if (this != &other) {
            this->height = std::exchange(other.height, 0);
            this->width = std::exchange(other.width, 0);
            this->data = std::exchange(other.data, nullptr);
        }
        return *this;
    }
    virtual ~Matrix() {
        data = destruct(data, height);
    }
    // конструктор с генерацией значений
    template<typename Generator>
    Matrix(std::size_t height, std::size_t width, Generator g) : height(height), width(width), data(generate(construct(height, width), height, width, g)) {}
вот это получается не нужно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
template<typename T>
Matrix<T> operator+(const Matrix<T>& a, const Matrix<T>& b) {
    if (a.getWidth() != b.getWidth() || a.getHeight() != b.getHeight()) {
        throw std::invalid_argument("matrices should be of the same dimension sizes");
    }
    Matrix<T> result(a.getHeight(), a.getWidth());
    for (std::size_t i = 0; i < a.getHeight(); ++i) {
        for (std::size_t j = 0; j < a.getWidth(); ++j) {
            result(i, j) = a(i, j) + b(i, j);
        }
    }
    return result;
}
А если я уберу вот эти проверки, то может можно будет вводить не только квадратные матрицы? Или здесь это именно особенность программы?

Подскажите еще пожалуйста, для чего нужен этот оператор?
C++
1
2
3
4
5
6
7
8
9
10
// оператор ввода матрицы из потока
template<typename T>
std::istream& operator>>(std::istream& in, Matrix<T>& m) {
    for (std::size_t i = 0; i < m.getHeight(); ++i) {
        for (std::size_t j = 0; j < m.getWidth(); ++j) {
            in >> m(i, j);
        }
    }
    return in;
}
И вот этот? До этого же уже есть функция умножения матриц, тогда этот что делает?

C++
1
2
3
4
5
6
7
8
9
10
template<typename T>
Matrix<T> operator*(const Matrix<T>& a, const T& scalar) {
    Matrix<T> result(a.getHeight(), a.getWidth());
    for (std::size_t i = 0; i < result.getHeight(); ++i) {
        for (std::size_t j = 0; j < result.getWidth(); ++j) {
            result(i, j) = a(i, j) * scalar;
        }
    }
    return result;
}
0
2832 / 2335 / 707
Регистрация: 29.06.2020
Сообщений: 8,651
14.11.2021, 12:44 4
vell1,
C++
1
std::istream& operator>>(std::istream& in, Matrix<T>& m)
выводит матрицу в поток (консоль, файл).
C++
1
Matrix<T> operator*(const Matrix<T>& a, const T& scalar)
умножение матрицы(всех элементов) на скалярную величину (число).
2
4773 / 2582 / 894
Регистрация: 29.11.2010
Сообщений: 5,590
14.11.2021, 13:27 5
Цитата Сообщение от vell1 Посмотреть сообщение
Да, там ошибка, должны фигурировать только матрицы
Поподробнее с этого места. Какая ошибка? Что "фигурирует" кроме матриц?

Цитата Сообщение от vell1 Посмотреть сообщение
вот это получается не нужно
Из этого всего вам не нужен только конструктор с генерацией значений.

Остальное как раз ОЧЕНЬ нужно. Без этого работать будет с ошибками. Там конструктор копирования, деструктор, оператор присваивания... Всё это нужно, чтоб класс работал правильно.

Цитата Сообщение от vell1 Посмотреть сообщение
А если я уберу вот эти проверки, то может можно будет вводить не только квадратные матрицы? Или здесь это именно особенность программы?
Это - оператор сложения. Он складывает две матрицы.
Матрицы можно складывать только если они одного размера.
Эта проверка проверяет, что складываются матрицы одного размера.

Вводить вы можете любые матрицы, а вот производить над ними действия -- не любые. Если вы уберёте проверку, ошибка всё равно будет, только другая и менее понятная.

Из-за математики.

Умножение матриц определено только для матриц, у которых количество столбцов первой равно количеству строк второй, а сложение определено только для матриц одного размера.

И оба эти действия одновременно возможны только для квадратных матриц.

Добавлено через 1 минуту
Цитата Сообщение от vell1 Посмотреть сообщение
Подскажите еще пожалуйста, для чего нужен этот оператор?
Цитата Сообщение от SmallEvil Посмотреть сообщение
умножение матрицы(всех элементов) на скалярную величину (число).
Уважаемый SmallEvil, уже ответил на этот вопрос.
Первый оператор вам понадобится, второй -- скорее всего нет.


Выложите задание целиком, как его дал преподаватель. Посмотрим, что можно сделать.
1
1 / 1 / 0
Регистрация: 11.10.2021
Сообщений: 11
14.11.2021, 20:37  [ТС] 6
lemegeton,
Поподробнее с этого места. Какая ошибка? Что "фигурирует" кроме матриц?
Это я про условие уточнил, что вы правы по поводу ошибки в задании.
Это ошибка? Опечатка?
Выложите задание целиком, как его дал преподаватель. Посмотрим, что можно сделать.
Это и было все задание))

Первый оператор вам понадобится, второй -- скорее всего нет.
Да, с этим разобрался

И оба эти действия одновременно возможны только для квадратных матриц
Большое спасибо за объяснения, а то я сразу не так понял про квадратные матрицы)
1
14.11.2021, 20:37
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.11.2021, 20:37
Помогаю со студенческими работами здесь

Создать класс динамического массива Array
Можете помочь создать это. Создайте класс Array (или используйте ранее созданный вами). Класс...

Создать класс Array и перегрузить операторы
Здравствуйте, у меня проблема при перегрузке операторов +-/*, я сделал их, но перегрузка не...

Создать шаблонный класс - контейнер Array
Доброго время суток, нужна помощь в реализации следующего задания: Создать шаблонный класс -...

Создать шаблонный класс-контейнер Array, который представляет собой массив
Создать шаблонный класс-контейнер Array, который представляет собой массив, позволяющий хранить...

Создать базовый класс Array, в котором определите поле-массив подходящего типа
Всем привет!!! Создать базовый класс Array, в котором определите поле-массив подходящего типа и...

Создать иерархию классов: абстрактный базовый класс Array и производные классы AndArray и OnArray
Помогите написать программу, спасибо!!! Создать абстрактный базовый класс Array с виртуальными...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru