Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
17_Лабораторная_2.docx
Скачиваний:
4
Добавлен:
02.02.2023
Размер:
802.07 Кб
Скачать

Санкт-Петербургский государственный

электротехнический университет «ЛЭТИ» им. В.И. Ульянова (Ленина) (СПбГЭТУ)

Факультет компьютерных технологий и информатики

Кафедра ВТ

Отчет по теме №2

Множества как объект

Выполнил: студент гр. 8091 Гришин И.Д. ___________

Проверил: старший преподаватель Колинько П.Г. ___________

Санкт-Петербург

2020

Содержание

  1. Техническое задание 3

2. Формализация задания 3

3. Контрольные тесты 4

4. Временная сложность 5

5. Результаты измерения времени 5

Выводы 6 Список используемой литературы 7

Приложение 1 8

Приложение 2 10

Приложение 3 12

Приложение 4 14

  1. Цель работы

Сравнение процедурного и объектно-ориентированного подходов на примере задачи обработки множеств. Исследование эффекта от использования классов.

  1. Задание

Множество, содержащее цифры из A, не являющиеся об­щими для множеств B и C и не встречающиеся в D. То есть E=A\(B&C)\D

  1. Преобразовать программу из отчёта 1, чтобы множества были объектами некоторого класса, а операции над ними – функциями-членами этого класса. Добиться, чтобы main() во всех вариантах была одинакова, менялось только определение класса.

  2. В варианте «списки» перегрузить операции new и delete для элемента списка и зафиксировать изменение времени решения задачи для этого случая. Провести эксперимент по отслеживанию вызовов функции при вычислении пятого множества по четырём исходным.

3.Контрольные тесты

Рис 1. Проведение тестов в программе «Массивы»

Рис 2. Проведение тестов в программе «Списки»

Рис 3. Проведение тестов в программе «Массив битов»

Рис 4. Проведение тестов в программе «Машинное слово»

4. Результаты измерения времени

Способ представления (кол-во повторов цикла)

Среднее время обработки, ms

Массивы (100000)

2760161

Списки (100000)

8095051

Массив битов (100000)

24821

Машинное слово (100000)

9190

5. Выводы

В ходе выполнения данной лабораторной работы были исследованы возможности представления различных типов множеств как объектов. Преимущества данного

метода – в том, что код унифицируется, то есть, для вычисления пятого множества

по четырем заданным по другим правилам, нежели в данном задании, достаточно

лишь изменить выражение в главной функции программы. Из недостатков – небольшое усложнение структуры программы и кода. Время выполнения практически не зависит от выбранного метода.

6. Список используемой литературы

1. Колинько П. Г. Алгоритмы и структуры данных. Часть 1: Пособие к самостоятельной работе и курсовому проектированию. Вып. 2003 (для заочников). –– СПб., 2020. — Error: Reference source not found с.

7. Приложение

Приложение 1: Массивы

#include <iostream> using namespace std; class Set { private: static const int N = 10; // мощность универсума static int num; // счётчик множеств int n = 0; // мощность множества char tag, *A; // тег и память для множества public: Set(); // конструктор — по умолчанию Set(char); // конструктор множества Set(const Set &); // конструктор копии ~Set() { delete[] A; } // деструктор void Show(); // вывод множества на экран int power() { return n; } // получение мощности Set operator|(const Set &) const; // объединение Set operator&(const Set &) const; // пересечение Set operator~() const; // дополнение до универсума Set &operator|=(const Set &); Set &operator&=(const Set &); Set &operator=(const Set &); // оператор присваивания }; Set::Set() : n(0), tag('A' + num++), A(new char[N+1]) { A[0] = 0; std::cout << "Создано " << tag << "(" << n << ") = [" << A << "]" << endl; } Set::Set(char) : tag('A' + num++), A(new char[N+1]) { char U[] = {'0','1','2','3','4','5','6','7','8','9'}; for (int i = 0; i < N; i++) if (rand() % 2) A[n++] = U[rand() % N]; A[n] = 0; std::cout << "Создано " << tag << "(" << n << ") = [" << A << "]" << endl; } Set::Set(const Set &B) : tag('A' + num++), n(B.n), A(new char[N+1]) { char *dst(A), *src(B.A); while ((*dst++ = *src++)); std::cout << "Создано " << tag << "(" << n << ") = [" << A << "] из " << B.tag << std::endl; } Set Set::operator|(const Set &B) const { Set C(*this); return (C |= B); } Set Set::operator~() const { Set C; for (char c = '0'; c <= '9'; ++c) { // Цикл по универсуму bool f = true; for (int j = 0; j < n; ++j) if (c == A[j]) { f = false; break; } if (f) C.A[C.n++] = c; } C.A[C.n] = 0; return C; } Set &Set::operator|=(const Set &B) { for (int i = 0; i < B.n; ++i) { bool f = true; for (int j = 0; j < n; ++j) if (B.A[i] == A[j]) f = false; if (f) A[n++] = B.A[i]; } A[n] = 0; return *this; } Set &Set::operator&=(const Set &B) { Set C(*this); n = 0; for (int i = 0; i < C.n; ++i) { for (int j = 0; j < B.n; j++) if (C.A[i] == B.A[j]) A[n++] = C.A[i]; } A[n] = 0; // ограничитель строки std::cout << "Получено " << tag << "(" << n << ") = [" << A << "] = " << C.tag << "&" << B.tag << std::endl; return *this; } Set &Set::operator=(const Set &B) { if (this != &B) { char *dst(A), *src(B.A); n = B.n; while ((*dst++ = *src++)); tag = 'A' + num++; } return *this; } Set Set::operator&(const Set &B) const { Set C(*this); return (C &= B); } void Set::Show() { cout << endl << tag << " = [" << A << "]"; } int Set::num = 0; // Начальное значение счётчика множеств const long q0 = 1; // количество повторений цикла времени int main() { srand(static_cast<unsigned int>(time(nullptr))); Set A('A'), B('B'), C('C'), D('D'), E; clock_t start = clock(); for (long q = 0; q < q0; q++) { E = (A & ~(B & C) & ~D); } clock_t end = clock(); E.Show(); cout << endl << "Middle power = " << (A.power() + B.power() + C.power() + D.power() + E.power()) / 5 << endl; cout << "Time = " << end - start << " / " << q0 << endl; cin.get(); return 0; }

Приложение 2: Списки

#include <iostream> using namespace std; class List { char data; List *next; static const int maxmup = 300; static List mem[maxmup]; // Свободная память для элементов списков static int mup, mup0; public: List() : data('!'), next(nullptr) {} List(char data, List *n = nullptr) : data(data), next(n) { std::cout << "+" << data; } ~List() { if (this) { if (next) { delete next; } std::cout << "-" << data; data = '*'; } else cout << "<Пусто!>"; } static void *operator new(size_t) { return (mup < maxmup ? &mem[mup++] : nullptr); } static void operator delete(void *, size_t) {} static void release() { mup = mup0; } // Сбросить до фиксированного friend class Set; friend std::ostream &operator<<(std::ostream &o, List &S); friend void memOut(); }; std::ostream &operator<<(std::ostream &o, List &S) { for (List *p = &S; p; p = p->next) o << p->data; return o; } List List::mem[List::maxmup]; // "Свободная память" int List::mup = 0, List::mup0 = 0; void memOut() { std::cout << endl << endl << "Память элементов списков (всего - " << List::mup << ")" << endl; for (int i = 0; i < List::mup; ++i) cout << List::mem[i].data; } class Set { private: static const int N = 10; // Мощность универсума static int num; // Порядковый номер множества int n; // Мощность множества char tag; // Тег List *A; // Список элементов public: Set(); // конструкторпо умолчанию Set(char); // конструктор множества Set(const Set &); // конструктор копии Set(Set &&); // конструктор копии ~Set() { std::cout << "Удалено " << tag << "(" << n << ") = [" << *A << "]"; A->List::~List(); cout << std::endl; } // деструктор void Show(); // вывод множества на экран void swap(Set &other) { std::swap(tag, other.tag); std::swap(n, other.n); std::swap(A, other.A); } int power() { return n; } // получение мощности Set operator|(const Set &) const; // объединение Set operator&(const Set &) const; // пересечение Set operator~() const; // дополнение до универсума Set &operator|=(const Set &); Set &operator&=(const Set &); Set &operator=(const Set &); // оператор присваивания }; Set::Set() : n(0), tag('A' + num++), A(nullptr) { std::cout << "→ Создано " << tag << "(" << n << ") = [" << *A << "]" << endl; } Set::Set(char) : tag('A' + num++), n(0) { A = nullptr; for (int i = 0; i < N; i++) if (rand() % 2) A = new List(i + '0', A), ++n; std::cout << "→ Создано " << tag << "(" << n << ") = [" << *A << "]" << endl; } Set::Set(const Set &B) : n(B.n), tag('A' + num++), A(nullptr) { for (List *p = B.A; p; p = p->next) A = new List(p->data, A); std::cout << "→ Создано " << tag << "(" << n << ") = [" << *A << "] из " << B.tag << std::endl; } Set::Set(Set &&B) : n(B.n), tag('A' + num++), A(B.A) { B.A = nullptr; std::cout << "→ Принято " << tag << "(" << n << ") = [" << *A << "] из " << B.tag << std::endl; } Set &Set::operator&=(const Set &B) { Set C; for (List *i = A; i; i = i->next) { for (List *j = B.A; j; j = j->next) if (i->data == j->data) C.A = new List(i->data, C.A), ++C.n; } swap(C); std::cout << "→ Получено " << tag << "(" << n << ") = [" << *A << "] = " << C.tag << "&" << B.tag << std::endl; return *this; } Set Set::operator&(const Set &B) const { Set C(*this); std::cout << endl << "Вычисление " << C.tag << " & " << B.tag << std::endl; return C &= B; } Set &Set::operator|=(const Set &B) { Set C(*this); for (List *i = B.A; i; i = i->next) { bool f = true; for (List *j = A; f && j; j = j->next) f = f && (i->data != j->data); if (f) C.A = new List(i->data, C.A), ++C.n; } swap(C); std::cout << "→ Получено " << tag << "(" << n << ") = [" << *A << "] = " << C.tag << "|" << B.tag << std::endl; return *this; } Set Set::operator|(const Set &B) const { Set C(*this); std::cout << endl << "Вычисление " << C.tag << " | " << B.tag << std::endl; return C |= B; } Set Set::operator~() const { Set C; for (char c = '0'; c <= '9'; ++c) { // цикл по универсуму bool f = true; for (List *j = A; j && f; j = j->next) if (c == j->data) f = false; if (f) C.A = new List(c, C.A), ++C.n; } std::cout << "→ Получено " << C.tag << "(" << C.n << ") = [" << *C.A << "] = ~" << tag << std::endl; return C; } Set &Set::operator=(const Set &B) { if (this != &B) { std::cout << endl << "Удалено " << tag << "(" << n << ") = [" << *A << "]"; delete A; A = nullptr; n = 0; for (List *p = B.A; p; p = p->next) A = new List(p->data, A), ++n; tag = 'A' + num++; } std::cout << "; Создано " << tag << "(" << n << ") = [" << *A << "] из " << B.tag << std::endl; return *this; } void Set::Show() { std::cout << endl << tag << "(" << hex << A << ") = [ "; for (List *p = A; p; p = p->next) std::cout << p->data << " "; std::cout << "]" << endl; } int Set::num = 0; const double q0 = 1; int main() { srand(static_cast<unsigned int>(time(nullptr))); // чтобы генерировать постоянно рандомные мн-ва { List::release(); Set A('A'), B('B'), C('C'), D('D'), E; cout << endl << "Результат: " << endl; clock_t start = clock(); for (long q = 0; q < q0; q++) { E = (A & ~(B & C) & ~D); } clock_t end = clock(); E.Show(); cout << "Middle power = " << (A.power() + B.power() + C.power() + D.power() + E.power()) / 5 << endl; cout << "Time = " << end - start << " / " << q0 << endl; cout << endl << "=== pause ===" << endl; cin.get(); } memOut(); cout << endl << "Всё!" << endl << "=== pause ===" << endl; cin.get(); return 0; }

Приложение 3: Байты

#include <iostream> #include <cstdlib> #include <ctime> using namespace std; class Set { private: static int N; // мощность универсума static int num; // счётчик множеств int n = 0; // мощность множества char tag, // тег A[10]; // и память для множества public: Set(); // конструкторпо умолчанию Set(char); // конструктор множества void Show(); // вывод множества на экран int power() const { return n; } // получение мощности Set operator&(const Set &) const; // пересечение Set operator~() const; // дополнение до универсума Set operator&=(const Set &); Set operator=(const Set &); // оператор присваивания }; int Set::N = 10; Set::Set() : tag('A' + num++), n(0) { A[n] = { 0 }; } Set::Set(char) : tag('A' + num++), n(0) { for (int i = 0; i < N; ++i) n += A[i] = rand() % 2; std::cout << tag << " = ["; for (int i = N - 1; i >= 0; --i) { if (A[i]) std::cout << char(i + '0'); else std::cout << "-"; } std::cout << "]" << endl; } Set Set::operator~() const { //Дополнение до универсума, с подсчётом мощности Set C; for (int i = 0; i < N; ++i) C.n += C.A[i] = !A[i]; return C; } Set Set::operator&=(const Set &B) { n = 0; for (int i = 0; i < N; ++i) n += A[i] = A[i] &= B.A[i]; return *this; } Set Set::operator=(const Set &B) { if (this != &B) { for (int i = 0; i < N; i++) { A[i] = B.A[i]; tag= 'A' + num++; } return *this; } } Set Set::operator&(const Set &B) const { Set C(*this); return (C &= B); } void Set::Show() { cout << endl << tag << " = ["; for (int i = Set::N - 1; i >= 0; --i) { if (A[i]) cout << char(i + '0'); else cout << "-"; } cout << "]"; } int Set::num = 0; const long q0 = 1; // количество повторений цикла времени int main() { srand(static_cast<unsigned int>(time(nullptr))); Set A('A'), B('B'), C('C'), D('D'), E; clock_t start = clock(); for (long q = 0; q < q0; q++) { E = (A & ~(B & C) & ~D); } clock_t end = clock(); E.Show(); cout << endl << "Middle power = " << (A.power() + B.power() + C.power() + D.power() + E.power()) / 5 << endl; cout << "Time = " << end - start << " / " << q0 << endl; cin.get(); return 0; }

Приложение 4: Слова

#include <iostream> #include <cstdlib> #include <ctime> using namespace std; class Set { private: static int const N = 10; // мощность универсума static int num; // счётчик множеств int n = 0; // мощность множества char tag; // тег int A; // и память для множества public: Set(); // конструкторпо умолчанию Set(char); // конструктор множества void Show(); // вывод множества на экран int power() const { return n; } // получение мощности Set operator&(const Set &) const; // пересечение Set operator~() const; // дополнение до универсума Set operator&=(const Set &); Set operator=(const Set &); // оператор присваивания }; Set::Set() : tag('A' + num++), n(0) { A = 0; } Set::Set(char) : tag('A' + num++), n(0) { A = rand(); std::cout << tag << " = ["; for (int i = 0; i < Set::N; i++) { if ((A >> i) & 1) std::cout << char(i + '0'); else std::cout << "-"; } std::cout << "]" << endl; } Set Set::operator~() const { //Дополнение до универсума, с подсчётом мощности Set C; C.A = ~A; return C; } Set Set::operator&=(const Set &B) { n = A = A &= B.A; return *this; } Set Set::operator=(const Set &B) { if (this != &B) { n = B.N; A = B.A; tag= 'A' + num++; return *this; } } Set Set::operator&(const Set &B) const { Set C(*this); return (C &= B); } void Set::Show() { cout << endl << tag << " = ["; for (int i = 0; i < Set::N; i++) { if ((A >> i) & 1) cout << char(i + '0'); else cout << "-"; } cout << "]"; } int Set::num = 0; const long q0 = 1; // количество повторений цикла времени int main() { srand(static_cast<unsigned int>(time(nullptr))); Set A('A'), B('B'), C('C'), D('D'), E; clock_t start = clock(); for (long q = 0; q < q0; q++) { E = (A & ~(B & C) & ~D); } clock_t end = clock(); E.Show(); cout << endl << "Middle power = " << (A.power() + B.power() + C.power() + D.power() + E.power()) / 5 << endl; cout << "Time = " << end - start << " / " << q0 << endl; cin.get(); return 0; }

15