Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

b = {"x"=>99,"у"=>88,"z"=>77}

intersection = a.keys & b.keys

difference = a.keys - b.keys

с = a.dup.update(b)

inter = {}

intersection.each {|k| inter[k]=c[k] }

# inter равно {"z"=>77}

diff={}

difference.each {|k| diff[k]=c[k] }

# diff равно {"а"=>1, "b"=>2}

8.2.14.

Хэш как разреженная матрица

Часто в массиве или матрице заполнена лишь небольшая часть элементов. Можно хранить их как обычно, но такое расходование памяти неэкономно. Хэш позволяет хранить только реально существующие значения.

В следующем примере предполагается, что несуществующие значения по умолчанию равны нулю:

values = Hash.new(0)

values[1001] = 5

values[2010] = 7

values[9237] = 9

x = values[9237] # 9

y = values[5005] # 0

Ясно, что обычный массив в таком случае содержал бы более 9000 неиспользуемых элементов, что не всегда приемлемо.

А если нужно реализовать разреженную матрицу размерности два или более? В этом случае можно было бы использовать массивы в качестве ключей:

cube = Hash.new(0)

cube[[2000,2000,2000]] = 2

z = cube[[36,24,36]] # 0

Здесь обычная матрица содержала бы миллиарды элементов.

8.2.15. Реализация хэша с повторяющимися ключами

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

В листинге 8.1 предложено частичное решение. Оно неполно по двум причинам. Во-первых, мы не стали реализовывать всю желательную функциональность, ограничившись лишь некоторым достаточно представительным подмножеством. Во-вторых, внутреннее устройство Ruby таково, что литеральный хэш всегда является экземпляром класса Hash, и, хотя мы наследуем классу Hash, литерал все равно не сможет содержать повторяющихся ключей (мы подумаем об этом позже).

Листинг 8.1. Хэш с повторяющимися ключами

class HashDup

 def initialize(*all)

raise IndexError if all.size % 2 != 0

@store = {}

if all[0] # не nil

keyval = all.dup

while !keyval.empty?

key = keyval.shift

if @store.has_key?(key)

@store[key] += [keyval.shift]

else

@store[key] = [keyval.shift]

end

end

end

 end

 def store(k,v)

if @store.has_key?(k)

@store[k] += [v]

else

@store[k] = [v]

end

 end

 def [](key)

@store[key]

 end

 def []=(key,value)

self.store(key,value)

 end

 def to_s

@store.to_s

 end

 def to_a

@store.to_a

 end

 def inspect

@store.inspect

 end

 def keys

result=[]

@store.each do |k,v|

result += ([k]*v.size)

end

result

 end

 def values

@store.values.flatten

 end

 def each

@store.each {|k,v| v.each {|y| yield k,y}}

 end

 alias each_pair each

 def each_key

self.keys.each {|k| yield k}

 end

 def each_value

self.values.each {|v| yield v}

 end

 def has_key? k

self.keys.include? k

 end

 def has_value? v

self.values.include? v

 end

 def length

self.values.size

 end

 alias size length

 def delete k

val = @store[k]

@store.delete k

val

 end

 def delete k,v

@store[k] -= [v] if @store[k]

Поделиться:
Популярные книги

Озноб

Малышева Анна Витальевна
Детективы:
прочие детективы
7.44
рейтинг книги
Озноб

Хроники Максима. Трилогия

Бадей Сергей
Фантастика:
юмористическое фэнтези
8.26
рейтинг книги
Хроники Максима. Трилогия

Королева Тьмы

Бишоп Энн
3. Черные драгоценности
Фантастика:
фэнтези
9.13
рейтинг книги
Королева Тьмы

Worm

Дж Мак Крей
Фантастика:
боевая фантастика
киберпанк
6.25
рейтинг книги
Worm

Князь Медведев. Дилогия

Вяч Павел
Медведев
Фантастика:
аниме
фэнтези
попаданцы
5.67
рейтинг книги
Князь Медведев. Дилогия

Посторонний. Миф о Сизифе. Калигула. Записные книжки 1935-1942

Камю Альбер
1. Библиотека классики
Драматургия:
пьесы
зарубежная драматургия
5.00
рейтинг книги
Посторонний. Миф о Сизифе. Калигула. Записные книжки 1935-1942

Т. 03 Гражданин Галактики

Хайнлайн Роберт Энсон
3. Отцы-основатели. Весь Хайнлайн
Фантастика:
научная фантастика
7.00
рейтинг книги
Т. 03 Гражданин Галактики

Собрание сочинений

Гримм Якоб и Вильгельм
Детские:
прочая детская литература
5.00
рейтинг книги
Собрание сочинений

Мир приключений 1967 г. №13

Булычев Кир
Альманах "Мир приключений"
Фантастика:
научная фантастика
5.00
рейтинг книги
Мир приключений 1967 г. №13

Вечный зов. Знаменитый роман в одном томе

Иванов Анатолий Степанович
Проза:
современная проза
9.15
рейтинг книги
Вечный зов. Знаменитый роман в одном томе

Найди себя!, или Ключ к изменению своей судьбы

Пинт Александр Александрович
Научно-образовательная:
психология
5.00
рейтинг книги
Найди себя!, или Ключ к изменению своей судьбы

"Фантастика 2023-116". Компиляция. Книги 1-18

Злотников Роман Валерьевич
Фантастика 2023. Компиляция
Фантастика:
фэнтези
боевая фантастика
5.00
рейтинг книги
Фантастика 2023-116. Компиляция. Книги 1-18

Victory значит победа

Tora_san
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Victory значит победа

Газлайтер. Том 4

Володин Григорий Григорьевич
4. История Телепата
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Газлайтер. Том 4