Хэш таблица и сет
Ранее мы поговорили поговорили о такой структуре данных как массив. Настало время поговорить про остальные базовые структуры данных
Хэш
Хэш таблица (еще она называется Hash map в других ЯП) - структура данных, хранящая в себе сразу 2 элмента - ключ и значение. Ключ - уникальный, значение - нет.
# создание пустой хэш таблицы
hash = Hash.new
# Упрощенная запись
hash = {}
# Способ создания хэш таблицы с заранее созданным содержанием
hash = Hash['key_1' => 'value_1', 'key_2' => 'value_2', 'key_1' => 'value_3']
# Упрощенная запись через кавычки
hash = {'key_1' => 'value_1', 'key_2' => 'value_2', 'key_1' => 'value_3'}
# Начиная с ruby 1.9 появилась возможность записывать ключ - значение через двоеточие.
# Данный вариант записи стоит считать наиболее предпочтительный, вместо Hash[...] или использования =>
# так как при записи key: value, key приводится к символу, о котором мы поговорим в следующем уроке
hash = {'key_1': 'value_1', 'key_2': 'value_2', 'key_1': 'value_3'}
# Обрати внимание, что key_1 содержится только один раз, не смотря на то, что мы его объявляли дважды
# И значение содержится от последней объявляенной пары с таким же ключом
puts hash # = {'key_1' => 'value_3', 'key_2' => 'value_2'}
Легче всего представлть хэш таблицу как словарь. Если открыть любой словарь, то мы увидим в нем слово и его перевод/ы. При этом один и тот же перевод, может относиться к различным словам. Давайте попробуем реализовать такой словарь с помощью Hash:
Теперь стоит обсудить как изменять хэш таблицу:
Давайте посмотрим на особенность итерации хэша в цикле:
Сет
Настало поговорить про Set. Set - это нечто среднее между массивом и хэш таблицей. Сет - это тот же самый Hash, но без значений, только ключи.
Сравнение Set vs Array
Хоть базовые алгоритмы мы изучим в дальнейшем, но сейчас важно понимать в чем приемущество Set по сравнению с Array
Рассмотрим такой метод как .include? который присутствует и у Array и у Set
Попробуйте запустить код у себя локально и сравнить время работы одних и тех же методов у разных структур.
Проверили ? Да, разница впечатляющая. Все дело в особенности работы этих структур. Метод .unclude? у Array обходит все свои элементы и проверяет на соотвествие (==). Сначала 1 элемент, потом 2, потом 3 и тд. Чем больше элементов, тем дольше может работать unclude?.
Семейство хэш структур одновременно знают все о своих ключах. Даже если увеличить размер структуры в десять раз или в сотню, скорость от этого не меняется. Это называется константное время, когда скорость доступа к элементу не меняется при изменении размера самой структуры. Так как Set это тот же самый Hash, но без значений, то правило и применимо для него.
Возможно у вас появилась мысль а зачем тогда испоьзовать массив если есть сет ? Всему свое место. Set - отлично, когда нам целенаправлено нужно использовать уникальность знчений. Если посмотреть на разницу во времени на добавление элементов, то заметим внушительный перевес по скорости у массива.
В дальнейших главах мы подробно изучим за счет чего такие структуры знают где искать свои ключи, почему для сета нужно гораздо больше времени н добавление, чем массиву, но пока нужно запомнить и держать в уме:
У массива доступ к элементу по значению прямо зависит от размера самого массива
У хэш таблицы и сета доступ по ключу не зависит от размера структуры, за счет чего действие происходит мгновенно
Задание key_vs_value
У Hash также имеются методы value?, который проверяет на наличие значения, и key?, который проверяет на наличие ключ.
Перепишите пример со сравнением скорости массива и сета на сравнение скорости метода
value?иkey?, переписав также метод добавления элементов, где ключ и значение это одно и тоже значение для хэш таблицыРасскажите о выводах которые вы можете сделать касаемо этих методов, после изучения полученных результатов
Задание email_checker
Задание на умение работать сетом.
Напишите программу, в которой будет храниться перечень адресов электронной почты. Адреса можно добавлять через консоль командой ADD и печатать весь список командой LIST.
Программа должна проверять корректность вводимых email’ов (вспоминаем прошлый урок) и печатать сообщение об ошибке при необходимости.
Принцип работы команд
LIST — выводит список электронных адресов.
ADD — проверяет и, если формат адреса верный, добавляет в множество.
Примеры команд
LIST
ADD ruby_course@rambler.ru
Команды вводятся одной строкой пользователем в консоль.
Задание phone_book
Задание на умение работать с хэш таблицей.
Напишите программу, которая будет работать как телефонная книга:
Если пишем новое имя, программа просит ввести номер телефона и запоминает его. Если новый номер телефона — просит ввести имя и также запоминает.
Если вводим существующее имя или номер телефона, программа выводит всю информацию о контакте.
При вводе команды LIST программа печатает в консоль список всех абонентов в алфавитном порядке с номерами.
Определяйте имя и телефон с помощью регулярных выражений.
Подумайте, что выбрать в качестве ключа и значения для хэш таблицы, выберите лучший вариант по вашему мнению. Опишите, какие минусы и плюсы видите в вашем выборе.
Last updated