Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3 сем / лаб2.docx
Скачиваний:
0
Добавлен:
06.06.2025
Размер:
115.14 Кб
Скачать

Минобрнауки России

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

Электротехнический университет

«ЛЭТИ» им. В.И. Ульянова (Ленина)

Кафедра вычислительной техники

Отчёт

Лабораторная работа №2

По дисциплине «АиСД»

Тема: множества как классы

Студент гр. 3316

Руденский И.М.

Преподаватель

Манирагена Валенс

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

2024

Постановка задачи

Цель работы: исследование четырёх способов хранения множеств в памяти ЭВМ с использованием классов.

Задание на обработку множеств:

Русские буквы

Множество, содержащее буквы, имеющиеся в A или об­щие для B и C, но не встречающиеся в D

Формализация задания: E = (A ∪ (B ∩ C)) \ D

Ход работы

1) Представим множества как массив символов. Возьмём как пример множеств мою фамилию, а также фамилии троих моих друзей.

a = РУДЕНСКИЙ

b = ЧЕТВЕРТАК

c = КИРЕЙКОВА

d = КОТОВ

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

Результат для массива символов:

Рисунок 1 - Результат для массива символов

2) Повторим то же самое, но представим множества в виде списков.

Рисунок 2 - Результат для списков

3) Повторим то же самое, но представим множества в виде машинных слов.

Рисунок 3 - Результат для машинных слов

4) Повторим то же самое, но представим множества в виде массивов байт.

Рисунок 4 - Результат для массивов байт

Получили следующие результаты: самый быстрый способ – машинные слова.

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

Массив символов

Список

Массив байт

Машинные слова

Время без использования классов, мс

29

28

26

25

Время с использованием классов

21

18

15

7

Вывод

В результате сравнения методов без использования классов и с их использованием можно сделать вывод, что программы с классами работают примерно в 2-3 раза быстрее (см. таблицу результатов измерения времени). На скриншотах из контрольных примеров показано, как вызываются функции и разрушаются объекты. Все описанные функции вызываются так, как и предусмотрено. Так же, как и в прошлой лабораторной работе, использование машинных слов в основе класса Set показало наиболее эффективный результат работы (разница в 3 раза по сравнению с массивом символов). Очевидно, что использование классов целесообразно, т.к. это делает код гораздо более читаемым, расширяет универсальность программы и ускоряет её работу.

Использованные источники

1) Бьёрн Страуструп – Язык программирования С++, 1986г.

2) Скотт Майерс - Эффективный и современный С++, 2014г.

Текст программы

main.cpp

#include "CharArrSet.h"

#include "ListSet.h"

#include "WordSet.h"

#include "BitArrSet.h"

#include <locale>

int main()

{

setlocale(LC_ALL, "russian");

BitArrSet a{ "РУДЕНСКИЙ" };

BitArrSet b{ "ЧЕТВЕРТАК" };

BitArrSet c{ "КИРЕЙКОВА" };

BitArrSet d{ "КОТОВ" };

b.Intersect(c);

b.Print();

a.Union(b);

a.Print();

a.Substract(d);

a.Print();

}

CharArrSet.h

#pragma once

#include <string>

#include <chrono>

class CharArrSet

{

public:

CharArrSet(const std::string &other);

~CharArrSet();

void Intersect(CharArrSet& other);

void Union(CharArrSet& other);

void Substract(CharArrSet& other);

void Print();

std::string &Get();

private:

std::string set;

std::chrono::system_clock::time_point start;

std::chrono::system_clock::time_point end;

};

CharArrSet.cpp

#include "CharArrSet.h"

#include <iostream>

CharArrSet::CharArrSet(const std::string &other)

{

std::cout << "Creating set object\n";

start = std::chrono::system_clock::now();

set = other;

}

CharArrSet::~CharArrSet()

{

std::cout << "Destroying set object\n";

end = std::chrono::system_clock::now();

auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

std::cout << "Miliseconds passed: " << elapsed.count() << '\n';

}

void CharArrSet::Intersect(CharArrSet& other)

{

std::cout << __FUNCTION__ << std::endl;

const char* arr1 = set.c_str();

const char* arr2 = other.Get().c_str();

std::string result;

result.resize(100);

int k = 0; // Индекс для записи пересечения в result

// Для каждого элемента в arr1 проверяем, есть ли он в arr2

for (int i = 0; i < strlen(arr1); ++i) {

for (int j = 0; j < strlen(arr2); ++j) {

if (arr1[i] == arr2[j]) {

// Проверяем, не был ли этот элемент уже добавлен в результат

bool alreadyExists = false;

for (int l = 0; l < k; ++l) {

if (result[l] == arr1[i]) {

alreadyExists = true;

break;

}

}

// Если элемент не добавлен ранее, добавляем его в результат

if (!alreadyExists) {

result[k++] = arr1[i];

}

break; // Достаточно найти одно совпадение

}

}

}

result[k] = '\0'; // Завершаем строку нулевым символом

set = result;

}

void CharArrSet::Union(CharArrSet& other)

{

std::cout << __FUNCTION__ << std::endl;

const char* arr1 = set.c_str();

const char* arr2 = other.Get().c_str();

std::string result;

result.resize(100);

int k = 0; // Индекс для записи в result

// Добавляем все уникальные элементы из arr1 в result

for (int i = 0; i < strlen(arr1); ++i) {

// Проверяем, не был ли этот элемент уже добавлен в результат

bool alreadyExists = false;

for (int l = 0; l < k; ++l) {

if (result[l] == arr1[i]) {

alreadyExists = true;

break;

}

}

// Если элемент не добавлен ранее, добавляем его в результат

if (!alreadyExists) {

result[k++] = arr1[i];

}

}

// Добавляем все уникальные элементы из arr2 в result

for (int i = 0; i < strlen(arr2); ++i) {

// Проверяем, не был ли этот элемент уже добавлен в result

bool alreadyExists = false;

for (int l = 0; l < k; ++l) {

if (result[l] == arr2[i]) {

alreadyExists = true;

break;

}

}

// Если элемент не добавлен ранее, добавляем его в результат

if (!alreadyExists) {

result[k++] = arr2[i];

}

}

result[k] = '\0'; // Завершаем строку нулевым символом

set = result;

}

void CharArrSet::Substract(CharArrSet& other)

{

std::cout << __FUNCTION__ << std::endl;

const char* arr1 = set.c_str();

const char* arr2 = other.Get().c_str();

std::string result;

result.resize(100);

int k = 0; // Индекс для записи в result

// Проходим по каждому элементу arr1

for (int i = 0; i < strlen(arr1); ++i) {

bool foundInArr2 = false;

// Проверяем, есть ли этот элемент в arr2

for (int j = 0; j < strlen(arr2); ++j) {

if (arr1[i] == arr2[j]) {

foundInArr2 = true;

break; // Элемент найден во втором массиве, пропускаем его

}

}

// Если элемент не найден во втором массиве, добавляем его в результат

if (!foundInArr2) {

result[k++] = arr1[i];

}

}

result[k] = '\0'; // Завершаем строку нулевым символом

set = result;

}

void CharArrSet::Print()

{

std::cout << __FUNCTION__ << std::endl;

std::cout << set << std::endl;

}

std::string &CharArrSet::Get()

{

std::cout << __FUNCTION__ << std::endl;

return set;

}

ListSet.h

#pragma once

#include <string>

#include <list>

#include <chrono>

class ListSet

{

public:

ListSet(const std::string &other);

~ListSet();

void Intersect(ListSet& list);

void Union(ListSet& list);

void Substract(ListSet& list);

void Print() const;

std::list<char>& Get();

private:

std::list<char> set;

std::chrono::system_clock::time_point start;

std::chrono::system_clock::time_point end;

};

ListSet.cpp

#include "ListSet.h"

#include <iostream>

ListSet::ListSet(const std::string& other)

{

std::cout << "Creating set object\n";

start = std::chrono::system_clock::now();

for (char c : other)

set.push_back(c);

}

ListSet::~ListSet()

{

std::cout << "Destroying set object\n";

end = std::chrono::system_clock::now();

auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

std::cout << "Miliseconds passed: " << elapsed.count() << '\n';

}

void ListSet::Intersect(ListSet& list)

{

std::cout << __FUNCTION__ << std::endl;

std::list<char> list2 = list.Get();

std::list<char> result;

for (char c : set) {

if (std::find(list2.begin(), list2.end(), c) != list2.end()) {

if (std::find(result.begin(), result.end(), c) == result.end()) {

result.push_back(c);

}

}

}

set = result;

}

void ListSet::Union(ListSet& list)

{

std::cout << __FUNCTION__ << std::endl;

std::list<char> list2 = list.Get();

std::list<char> result = set;

for (char c : list2) {

if (std::find(result.begin(), result.end(), c) == result.end()) {

result.push_back(c);

}

}

set = result;

}

void ListSet::Substract(ListSet& list)

{

std::cout << __FUNCTION__ << std::endl;

std::list<char> list2 = list.Get();

std::list<char> result;

for (char c : set) {

if (std::find(list2.begin(), list2.end(), c) == list2.end()) {

result.push_back(c);

}

}

set = result;

}

void ListSet::Print() const

{

std::cout << __FUNCTION__ << std::endl;

for (char c : set)

std::cout << c << " ";

std::cout << std::endl;

}

std::list<char>& ListSet::Get()

{

std::cout << __FUNCTION__ << std::endl;

return set;

}

WordSet.h

#pragma once

#include <string>

#include <chrono>

class WordSet

{

public:

WordSet(const std::string& other);

~WordSet();

void Intersect(WordSet& other);

void Union(WordSet& other);

void Substract(WordSet& other);

void Print();

uint32_t Get();

private:

uint32_t set;

const int ALPHABET_SIZE = 32;

std::chrono::system_clock::time_point start;

std::chrono::system_clock::time_point end;

};

WordSet.cpp

#include "WordSet.h"

#include <iostream>

typedef uint32_t Set;

WordSet::WordSet(const std::string& other)

{

std::cout << "Creating set object\n";

start = std::chrono::system_clock::now();

Set _set = 0;

for (char c : other) {

if (c >= 'А' && c <= 'Я') {

_set |= (1 << (c - 'А')); // Устанавливаем бит для буквы

}

}

set = _set;

}

WordSet::~WordSet()

{

std::cout << "Destroying set object\n";

end = std::chrono::system_clock::now();

auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

std::cout << "Miliseconds passed: " << elapsed.count() << '\n';

}

void WordSet::Intersect(WordSet& other)

{

std::cout << __FUNCTION__ << std::endl;

set &= other.Get();

}

void WordSet::Union(WordSet& other)

{

std::cout << __FUNCTION__ << std::endl;

set |= other.Get();

}

void WordSet::Substract(WordSet& other)

{

std::cout << __FUNCTION__ << std::endl;

set &= ~other.Get();

}

void WordSet::Print()

{

std::cout << __FUNCTION__ << std::endl;

for (int i = 0; i < ALPHABET_SIZE; ++i) {

if (set & (1 << i)) {

std::cout << static_cast<char>('А' + i);

}

}

std::cout << std::endl;

}

uint32_t WordSet::Get()

{

std::cout << __FUNCTION__ << std::endl;

return set;

}

BitArrSet.h

#pragma once

#include <string>

#include <chrono>

#include <bitset>

static const int ALPHABET_SIZE = 32;

class BitArrSet

{

public:

BitArrSet(const std::string& other);

~BitArrSet();

void Intersect(BitArrSet& other);

void Union(BitArrSet& other);

void Substract(BitArrSet& other);

void Print();

std::bitset<ALPHABET_SIZE> Get();

private:

std::bitset<ALPHABET_SIZE> set;

std::chrono::system_clock::time_point start;

std::chrono::system_clock::time_point end;

};

BitArrSet.cpp

#include "BitArrSet.h"

#include <iostream>

BitArrSet::BitArrSet(const std::string& other)

{

std::cout << "Creating set object\n";

start = std::chrono::system_clock::now();

for (char c : other) {

if (c >= 'А' && c <= 'Я') {

set.set(c - 'А'); // Помещаем буквы в нужный бит

}

}

}

BitArrSet::~BitArrSet()

{

std::cout << "Destroying set object\n";

end = std::chrono::system_clock::now();

auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

std::cout << "Miliseconds passed: " << elapsed.count() << '\n';

}

void BitArrSet::Intersect(BitArrSet& other)

{

std::cout << __FUNCTION__ << std::endl;

set &= other.Get();

}

void BitArrSet::Union(BitArrSet& other)

{

std::cout << __FUNCTION__ << std::endl;

set |= other.Get();

}

void BitArrSet::Substract(BitArrSet& other)

{

std::cout << __FUNCTION__ << std::endl;

set &= ~other.Get();

}

void BitArrSet::Print()

{

std::cout << __FUNCTION__ << std::endl;

for (int i = 0; i < ALPHABET_SIZE; ++i) {

if (set[i]) {

std::cout << static_cast<char>('А' + i);

}

}

std::cout << std::endl;

}

std::bitset<ALPHABET_SIZE> BitArrSet::Get()

{

std::cout << __FUNCTION__ << std::endl;

return set;

}

Соседние файлы в папке 3 сем