Мячина_4ЛР
.docxМИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ, СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ
Ордена Трудового Красного Знамени федеральное государственное бюджетное образовательное учреждение высшего образования
Московский технический университет связи и информатики
(МТУСИ)
Кафедра «Системное программирование»
Лабораторная работа №4
«Организация таблиц идентификаторов»
по дисциплине «Системное программное обеспечение»
Вариант 4
Выполнила:
студентка группы БФИ2203
Мячина Лада Андреевна
Проверила:
Старший преподаватель
Алексанян Диана Ашотовна
Москва, 2025 г.
Задание: разработать программу для сравнения двух методов организации таблиц идентификаторов с использованием хэш-адресации:
- Рехэширование с использованием псевдослучайных чисел;
- Простое рехэширование
Ход работы:
Принцип работы простого рехэшированиия: при возникновении коллизии осуществляется переход к следующей ячейке таблицы
Формула рехэширования: index = (index + 1) % size
Алгоритм поиска для простого рехэширования:
1. Вычислить хэш-значение идентификатора
2. Проверить ячейку с полученным индексом
3. Если ячейка содержит искомый идентификатор - поиск успешен
4. Если ячейка пуста - идентификатор не найден
5. Если ячейка содержит другой идентификатор:
- Перейти к следующей ячейке (index + 1)
- Повторить шаги 3-5
- Если вернулись к исходной ячейке
- идентификатор не найден
Принцип работы рехэширования с использованием псевдослучайных чисел: используется заранее сгенерированная последовательность псевдослучайных чисел
При коллизии: index = (original_index + random_sequence[attempt]) % size
Алгоритм поиска для случайного рехэширования:
1. Вычислить хэш-значение идентификатора
2. Проверить ячейку с полученным индексом
3. Если ячейка содержит искомый идентификатор - поиск успешен
4. Если ячейка пуста - идентификатор не найден
5. Если ячейка содержит другой идентификатор:
- Вычислить новый индекс используя псевдослучайную последовательность
- Повторить шаги 3-5
- Если исчерпана последовательность - идентификатор не найден
Листинг программы для выполнения ЛР:
import random
class HashTable:
def __init__(self, size=211):
self.size = size
self.table = [None] * size
self.comparison_count = 0
def reset_comparisons(self):
self.comparison_count = 0
def hash_function(self, identifier):
return sum(ord(c) for c in identifier) % self.size
class SimpleRehashTable(HashTable):
def insert(self, identifier):
index = self.hash_function(identifier)
original_index = index
while self.table[index] is not None:
index = (index + 1) % self.size
if index == original_index:
return False
self.table[index] = identifier
return True
def search(self, identifier):
self.reset_comparisons()
index = self.hash_function(identifier)
original_index = index
while self.table[index] is not None:
self.comparison_count += 1
if self.table[index] == identifier:
return True, self.comparison_count
index = (index + 1) % self.size
if index == original_index:
break
return False, self.comparison_count
class RandomRehashTable(HashTable):
def __init__(self, size=211):
super().__init__(size)
random.seed(42)
self.random_sequence = [random.randint(1, size-1) for _ in range(size)]
def insert(self, identifier):
index = self.hash_function(identifier)
original_index = index
attempt = 0
while self.table[index] is not None:
index = (original_index + self.random_sequence[attempt]) % self.size
attempt += 1
if attempt >= self.size:
return False
self.table[index] = identifier
return True
def search(self, identifier):
self.reset_comparisons()
index = self.hash_function(identifier)
original_index = index
attempt = 0
while self.table[index] is not None:
self.comparison_count += 1
if self.table[index] == identifier:
return True, self.comparison_count
index = (original_index + self.random_sequence[attempt]) % self.size
attempt += 1
if attempt >= self.size:
break
return False, self.comparison_count
def read_identifiers(filename):
identifiers = []
try:
with open(filename, 'r', encoding='utf-8') as f:
for line in f:
identifier = line.strip()
if identifier and len(identifier) <= 32:
identifiers.append(identifier)
except FileNotFoundError:
print(f"Файл {filename} не найден!")
return []
return identifiers
def main():
# Чтение идентификаторов
identifiers = read_identifiers("identifiers.txt")
if not identifiers:
print("Не удалось загрузить идентификаторы")
return
print(f"Загружено идентификаторов: {len(identifiers)}")
# Создание таблиц
simple_table = SimpleRehashTable()
random_table = RandomRehashTable()
# Вставка идентификаторов
for identifier in identifiers:
simple_table.insert(identifier)
random_table.insert(identifier)
print("Таблицы созданы успешно!")
# Тестирование поиска
print("\nТЕСТИРОВАНИЕ ПОИСКА")
# Поиск существующих идентификаторов
print("Поиск существующих идентификаторов:")
simple_comps = []
random_comps = []
for identifier in identifiers[:10]:
found_simple, comp_simple = simple_table.search(identifier)
found_random, comp_random = random_table.search(identifier)
simple_comps.append(comp_simple)
random_comps.append(comp_random)
print(f"{identifier}: простое={comp_simple}, случайное={comp_random}")
print(f"\nСреднее число сравнений:")
print(f"Простое рехэширование: {sum(simple_comps)/len(simple_comps):.2f}")
print(f"Случайное рехэширование: {sum(random_comps)/len(random_comps):.2f}")
# Интерактивный поиск
print("\nИНТЕРАКТИВНЫЙ ПОИСК")
print("Введите идентификатор для поиска (или 'exit' для выхода):")
while True:
user_input = input("> ").strip()
if user_input.lower() == 'exit':
break
found_simple, comp_simple = simple_table.search(user_input)
found_random, comp_random = random_table.search(user_input)
status_simple = "НАЙДЕН" if found_simple else "НЕ НАЙДЕН"
status_random = "НАЙДЕН" if found_random else "НЕ НАЙДЕН"
print(f"Простое рехэширование: {status_simple}, сравнений: {comp_simple}")
print(f"Случайное рехэширование: {status_random}, сравнений: {comp_random}")
print()
if __name__ == "__main__":
main()
Поиск существующих идентификаторов:
Тест на коллизии:
Поиск несуществующих идентификаторов:
