Добавил:
CanyonE
СПбГУТ * ИКСС * Программная инженерия
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Решения лабораторных работ (местами есть ошибки) / Lab1_SimpleArray
.cpp#include <iostream>
#include <stdexcept>
using std::cin;
using std::cout;
using std::endl;
// Класс «Массив»
class SimpleArray {
private:
// Размер массива
size_t n_ = 0;
// Число зарезервированных элементов (m_ >= n_)
size_t m_ = 0;
// Указатель на массив
double *values_ = nullptr;
public:
// Конструктор
explicit SimpleArray(size_t n = 0) : n_(n), m_(n) {
values_ = new double[m_] {0};
}
// Конструктор копирования
SimpleArray(const SimpleArray &arg) : n_(arg.n_), m_(arg.m_) {
if (m_ > 0) {
values_ = new double[m_] {0};
if (n_ > 0) {
std::copy(arg.values_, arg.values_ + arg.n_, values_);
}
}
}
// Оператор копирования
SimpleArray &operator=(const SimpleArray &arg) {
SimpleArray temp(arg);
swap(*this, temp);
return *this;
}
// Конструктор перемещения
SimpleArray(SimpleArray &&arg) noexcept {
values_ = arg.values_, n_ = arg.n_, m_ = arg.m_;
arg.values_ = nullptr, arg.n_ = 0, arg.m_ = 0;
}
// Оператор перемещения
SimpleArray &operator=(SimpleArray &&arg) noexcept {
if (this != &arg) {
swap(*this, arg);
delete[] arg.values_, arg.values_ = nullptr;
arg.n_ = 0, arg.m_ = 0;
}
return *this;
}
// Деструктор
virtual ~SimpleArray() {
delete[] values_;
}
// Очистка массива
void clear() {
delete[] values_, values_ = nullptr;
n_ = 0, m_ = 0;
}
// Получение элемента массива по индексу (не вызывает исключения)
double &operator[](size_t idx) {
return values_[idx];
}
// Объединение двух массивов
SimpleArray merge(const SimpleArray &arg) const {
SimpleArray temp(n_ + arg.n_);
if (n_) {
std::copy(values_, values_ + n_, temp.values_);
}
if (arg.n_) {
std::copy(arg.values_, arg.values_ + arg.n_, temp.values_ + n_);
}
return temp;
}
// Добавление элемента в конец массива
void push_back(const double &elem) {
if (n_ < m_) { // Если текущий размер меньше числа зарезервированных элементов
values_[n_] = elem; // Заполняем новый элемент
++n_;
return;
}
double *temp = values_; // Иначе генерируем новый массив
if (m_ == 0) {
m_ = 1;
}
m_ *= 2; // С размером вдвое большим предыдущего
values_ = new double[m_];
if (temp != nullptr) { // Если прежний массив существовал, то копируем из него значения
std::copy(temp, temp + n_, values_);
}
values_[n_] = elem; // Заполняем новый элемент
delete[] temp;
++n_;
}
// Удаление count элементов с позиции idx
void erase(size_t idx, size_t count) noexcept(false) {
if (idx + count <= n_) {
std::copy(values_ + idx + count, values_ + n_, values_ + idx); // Сдвиг конца массива влево ('удаление')
n_ -= count;
return;
}
throw std::invalid_argument("SimpleArray. Method erase. Index + Count > N");
}
// Получение размера массива
size_t size() const {
return n_;
}
// Произведение элементов массива и на число d
long double mul(double d = 1) const {
for (size_t i = 0; i < n_; ++i) {
d *= values_[i];
}
return d;
}
// Максимальный элемент массива
double max() const {
double mx = 0;
if (n_ > 0) {
mx = values_[0];
for (size_t i = 1; i < n_; ++i) {
if (values_[i] > mx) {
mx = values_[i];
}
}
}
return mx;
}
// Минимальный элемент массива
double min() const {
double mn = 0;
if (n_ > 0) {
mn = values_[0];
for (size_t i = 1; i < n_; ++i) {
if (values_[i] < mn) {
mn = values_[i];
}
}
}
return mn;
}
// Вставка одного массива в заданную позицию другого
SimpleArray insert(const SimpleArray &arg, size_t idx) const noexcept(false) {
if (idx <= n_) {
SimpleArray result(n_ + arg.n_); // (0, 0, 0, 0, 0, 0, 0)
std::copy(values_, values_ + idx, result.values_); // (1, 2, 0, 0, 0, 0, 0)
std::copy(arg.values_, arg.values_ + arg.n_, result.values_ + idx); // (1, 2, -3, -4, 0, 0, 0)
std::copy(values_ + idx, values_ + n_, result.values_ + idx + arg.n_); // (1, 2, -3, -4, 5, 6, 7)
return result;
}
throw std::invalid_argument("SimpleArray. Method insert. Index > N");
}
// Умножение всех элементов массива на заданное число
SimpleArray operator*(const double &d) const {
SimpleArray result(*this);
for (size_t i = 0; i < n_; ++i) {
result.values_[i] *= d;
}
return result;
}
// Деление всех элементов массива на заданное число
SimpleArray operator/(const double &d) const {
return ( *this * ( 1. / d ) );
}
// Оператор приведения к типу bool
explicit operator bool () {
return n_ != 0;
}
// Дружественный оператор для вывода элементов массива в выходной поток os (cout, ...)
friend std::ostream &operator<<(std::ostream &os, const SimpleArray &arg) {
if (arg.n_ > 0) {
os << arg.values_[0];
for (size_t i = 1; i < arg.n_; ++i) {
os << ' ' << arg.values_[i];
}
}
return os;
}
friend void swap(SimpleArray &first, SimpleArray &second) noexcept {
std::swap(first.values_, second.values_);
std::swap(first.m_, second.m_);
std::swap(first.n_, second.n_);
}
};
int main() {
const size_t N1 = 2, N2 = 5;
// Создание массивов
SimpleArray massA(N1), massB(N2);
// Вывод массивов и их размеров
cout << "Array A: " << massA << " (size: " << massA.size() << ")\n";
cout << "Array B: " << massB << " (size: " << massB.size() << ")\n";
// Заполнение массивов
for (size_t i = 0; i < N1; ++i) { massA[i] = rand() % 100; }
for (size_t i = 0; i < N2; ++i) { massB[i] = rand() % 100; }
// Вывод массивов
cout << "Array A: " << massA << " (size: " << massA.size() << ")\n";
cout << "Array B: " << massB << " (size: " << massB.size() << ")\n" << endl;
// Конструктор копирования
SimpleArray massC(massB);
cout << "1. Copy constructor:\n";
cout << "Array B: " << massB << " (size: " << massB.size() << ")\n";
cout << "Array C: " << massC << " (size: " << massC.size() << ")\n";
// Оператор копирования
massC = massA;
cout << "2. Copy assignment:\n";
cout << "Array A: " << massA << " (size: " << massA.size() << ")\n";
cout << "Array C: " << massC << " (size: " << massC.size() << ")\n";
// Конструктор перемещения
SimpleArray massD(std::move(massB));
cout << "3. Move constructor:\n";
cout << "Array B: " << massB << " (size: " << massB.size() << ")\n";
cout << "Array D: " << massD << " (size: " << massD.size() << ")\n";
// Оператор перемещения
massD = std::move(massA);
cout << "4. Move assignment:\n";
cout << "Array A: " << massA << " (size: " << massA.size() << ")\n";
cout << "Array D: " << massD << " (size: " << massD.size() << ")\n";
// Слияние (объединение) двух массивов в один
cout << "Merge (" << massC << " and " << massD << ") = " << massC.merge(massD) << endl;
cout << "Merge (" << massC.merge(massD) << " and " << massC.merge(massD) << ") = "
<< massC.merge(massD).merge(massC.merge(massD)) << endl;
// Очистка массива
massC.clear();
// Добавление элементов в конец массива
cout << "Array C (before add): " << massC << " (size: " << massC.size() << ")\n";
for (size_t i = 0; i < 100; ++i) { massC.push_back(i); }
// Удаление элементов из массива (idx, count)
cout << "Array C (after add): " << massC << " (size: " << massC.size() << ")\n";
massC.erase(5, 95);
cout << "Array C (after erase): " << massC << " (size: " << massC.size() << ")\n";
massC.erase(0, 5);
cout << "Array C (after erase): " << massC << " (size: " << massC.size() << ")\n";
// Произведение элементов массива
for (size_t i = 1; i <= 5; ++i) { massC.push_back(i); }
cout << "Array C: " << massC << " [mul(Array C): " << massC.mul() << "]\n";
cout << "Array C: " << massC << " [mul(Array C) * 6: " << massC.mul(6) << "]\n";
// Определение максимального и минимального элементов
cout << "Array C: " << massC << " [max(Array C): " << massC.max() << "]\n";
cout << "Array C: " << massC << " [min(Array C): " << massC.min() << "]\n";
// Умножение и деление элементов массива
cout << "Array C: " << massC << " [(Array C * 5) / 4: " << ( massC * 5 ) / 4 << "]\n";
// Вставка одного массива в заданную позицию другого
for (size_t i = 0; i <= massC.size(); ++i) {
cout << "Array C in Array C (" << i << "): " << massC.insert(massC, i) << endl;
}
}
Соседние файлы в папке Решения лабораторных работ (местами есть ошибки)