Добавил:
github.com Кофедра ВТ-помойка Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
30
Добавлен:
17.11.2018
Размер:
94.26 Кб
Скачать

МИНОБРНАУКИ РОССИИ

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

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

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

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

отчет

по лабораторной работе №3

по дисциплине «Алгоритмы и структуры данных»

Тема: «Хеш-таблицы»

Вариант №42

Студенты гр. 6307

Лазарев С.О.

Медведев Е.Р.

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

Колинько П.Г.

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

2018

СОДЕРЖАНИ

ЦЕЛЬ 3

ЗАДАНИЕ 3

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

ВЫВОДЫ 6

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 7

ПРИЛОЖЕНИЕ 8

ЗАДАНИЕ 3

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

ВЫВОДЫ 6

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 7

ПРИЛОЖЕНИЕ 8

ЦЕЛЬ 3

ЗАДАНИЕ 3

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

ВЫВОДЫ 6

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 7

ПРИЛОЖЕНИЕ 8

ЦЕЛЬ

Получить практические навыки по работе с хеш-таблицами.

ЗАДАНИЕ

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

F = (A & B) \ (C & D) ^ E.

Решение задачи

Пример:

Рис 1. Элементы множества А в хеш-таблице.

Рис 2. Элементы множества В в хеш-таблице.

Рис 3. Элементы множества С в хеш-таблице.

Рис 4. Элементы множества D в хеш-таблице.

Рис 5. Элементы множества E в хеш-таблице.

Рис 6. Результат вычисления A & B

Рис 7. Результат вычисления C & D

Рис 8. Результат вычисления (A & B) / (C & D)

Рис 9. Искомый результат F = (A & B) / (C & D) ^ E

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

Таблица 1. Временная сложность

В лучшем

В худшем случае

Расход памяти

O(n)

O(n)

Вставка

O(1)

O(n)

Удаление

O(1)

O(n)

XOR

O(n)

O(n^2)

&

O(n)

O(n^2)

\

O(n)

O(n^2)

F

O(n)

O(n^2)

ВЫВОДЫ

Мы получили навыки работы с хеш-таблицами. Размер таблицы выбран m = 6 для удобного представления на экране. Также это становится возможным с использованием цепочек переполнения. Коэффициенты a = 7 и b = 3 выбраны согласно рекомендации в методических указаниях. (a и b – простые числа, a близкое к m и b близкое к 1). Если пренебречь удобством, можно выбрать размер таблицы m = 2*U, где U – универсум (в нашем случае U = 66), чтобы снизить вероятность появления коллизий.

.

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

  1. Алгоритмы и структуры данных. – Методические указания к лабораторным работам, практическим занятиям и курсовому проектированию, часть 2, глава 1 «Работа с иерархией объектов: наследование и полиморфизм».

ПРИЛОЖЕНИЕ

main.cpp

#include "hash_set.h"

#include <time.h>

#include <iostream>

const int N = 66; // Мощность множества

HashSet generate();

int main()

{

srand(time(NULL));

HashSet a, b, c, d, e, f1,f2,f3,f4,f;

a = generate();

b = generate();

c = generate();

d = generate();

e = generate();

std::cout << "A:" << std::endl << a << std::endl;

std::cout << "B:" << std::endl << b << std::endl;

std::cout << "C:" << std::endl << c << std::endl;

std::cout << "D:" << std::endl << d << std::endl;

std::cout << "E:" << std::endl << e << std::endl;

std::cout << "-----------------------------------------------------" << std::endl;

f1 = a & b;

std::cout << "a & b" << std::endl << f1 << std::endl;

f2 = c & d;

std::cout << "c&d" << std::endl << f2 << std::endl;

f3 = ((a&b) / (c&d));

std::cout << "(a&b) / (c&d)" << std::endl << f3 << std::endl;

std::cout << "F = (A & B) / (C & D) ^ E" << std::endl << std::endl;

f = ((a&b) / (c&d)) ^ e;

std::cout << "F:" << std::endl << f << std::endl;

std::cin.get();

return 0;

}

HashSet generate()

{

HashSet result = HashSet();

static char *uni = new char[N];

int k = 48;

for (int i = 0; i < N-1; i++) {

uni[i] = k;

k++;

}

int count = rand() % (N + 1);

char x;

for (int i = 0; i < count; i++)

{

int p = rand() % (N - i);

if (p)

{

result.add(uni[p + i] - '0');

x = uni[i];

uni[i] = uni[i + p];

uni[i + p] = x;

}

}

return result;

}

HashSet.cpp

#include "hash_set.h"

Entry HashSet::null = Entry(-1);

int HashSet::dataSize = 6;

HashSet::HashSet()

{

data = new Entry *[dataSize];

for (int i = 0; i < dataSize; i++)

data[i] = &null;

};

HashSet::HashSet(const HashSet & set)

{

data = new Entry *[dataSize];

for (int i = 0; i < dataSize; i++)

data[i] = &null;

for (int i = 0; i < dataSize; i++)

for (Entry * j = set.data[i]; j != &null; j = j->next)

{

data[i] = new Entry(j->key, data[i]);

}

}

HashSet::HashSet(HashSet && set)

{

data = set.data;

size = set.size;

set.data = nullptr;

}

HashSet::~HashSet()

{

delete[] data;

}

int HashSet::hash(int key) const

{

return (7 * key + 3) % dataSize;

}

bool HashSet::add(int key)

{

int h = hash(key);

if (contains(key))

return false;

data[h] = new Entry(key, data[h]);

return true;

}

bool HashSet::contains(int key)const

{

int h = hash(key);

for (Entry * i = data[h]; i != &null; i = i->next)

if (key == i->key)

return true;

return false;

}

HashSet HashSet::operator=(const HashSet& set)

{

return HashSet(set);

}

HashSet HashSet::operator=(HashSet && set)

{

data = set.data;

size = set.size;

set.data = nullptr;

return *this;

}

HashSet HashSet::operator |(const HashSet& set)const

{

HashSet result = HashSet(set);

for (int i = 0; i < dataSize; i++)

for (Entry * j = data[i]; j != &null; j = j->next)

{

if (!result.contains(j->key))

result.add(j->key);

}

return result;

}

HashSet HashSet::operator /(const HashSet& set)const

{

HashSet result;

for (int i = 0; i < dataSize; i++)

for (Entry * j = data[i]; j != &null; j = j->next)

{

if (!set.contains(j->key))

result.add(j->key);

}

return result;

}

HashSet HashSet::operator &(const HashSet& set)const

{

HashSet result = HashSet();

for (int i = 0; i < dataSize; i++)

for (Entry * j = data[i]; j != &null; j = j->next)

{

if (set.contains(j->key))

result.add(j->key);

}

return result;

}

HashSet HashSet::operator ^(const HashSet& set)const

{

HashSet result = HashSet();

for (int i = 0; i < dataSize; i++)

for (Entry * j = data[i]; j != &null; j = j->next)

{

if (!set.contains(j->key))

result.add(j->key);

}

for (int i = 0; i < dataSize; i++)

for (Entry * j = set.data[i]; j != &null; j = j->next)

{

if (!contains(j->key))

result.add(j->key);

}

return result;

}

std::ostream& operator<<(std::ostream& os, const HashSet& set)

{

for (int i = 0; i < set.dataSize; i++)

{

os << "[" << i << "] : ";

for (Entry * j = set.data[i]; j != &HashSet::null; j = j->next)

{

os << j->key << " --> ";

}

os << " -|" << std::endl;

}

return os;

}

Hash_set.h

#pragma once

#include <iostream>

class Entry

{

public:

Entry * next;

int key;

Entry(int key, Entry * next = nullptr) :key(key), next(next) {};

~Entry()

{

delete next;

};

};

class HashSet

{

private:

Entry * * data;

static Entry null;

static int dataSize;

int size;

int hash(int key) const;

public:

HashSet();

HashSet(HashSet &&);

HashSet(const HashSet &);

~HashSet();

friend std::ostream & operator<<(std::ostream& os, const HashSet& set);

bool add(int key);

bool contains(int key)const;

HashSet operator=(const HashSet&);

HashSet operator=(HashSet &&);

HashSet operator |(const HashSet&)const;

HashSet operator &(const HashSet&)const;

HashSet operator ^(const HashSet&)const;

HashSet operator /(const HashSet&)const;

};

Соседние файлы в папке Колинько 4 семестр 2018