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

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

Жанры

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

Операция дополнения опирается на идею универсального множества. Однако «универсальное множество» в каждой конкретной ситуации определяется по-разному, поэтому лучшим решением будет самое простое: сначала определим, что такое универсальное множество, а потом вычислим разность.

universe = [1, 2, 3, 4, 5, 6]

а = [2, 3]

b = universe - а # Дополнение а = [1, 4, 5, 6]

Если считаете необходимым, можете определить и унарный оператор (например,

или
~
для выполнения этой операции.

Элементы

множества можно перебирать, обходя массив. Единственная разница заключается в том, что элементы будут появляться в определенном порядке, а это может оказаться нежелательным. О том, как перебирать массив в случайном порядке, будет рассказано в разделе 8.1.18.

Наконец, иногда возникает необходимость вычислить степень множества. Это не что иное, как множество всех подмножеств данного множества (включая его само и пустое множество). Читатели, знакомые с дискретной математикой, в особенности с комбинаторикой, понимают, что число таких подмножеств равно 2n. Сгенерировать степень множества можно следующим образом:

class Array

 def powerset

num = 2**size

ps = Array.new(num, [])

self.each_index do |i|

a = 2**i

b = 2**(i+1) — 1

j = 0

while j < num-1

for j in j+a..j+b

ps[j] += [self[i]]

end

j += 1

end

end

ps

 end

end

x = [1, 2, 3]

y = x.powerset

# y равно:

# [[], [1], [2], [1,2] , [3], [1,3], [2,3], [1,2,3]]

8.1.10. Рандомизация массива

Иногда нужно переставить элементы массива в случайном порядке. Первое, что приходит на ум, — тасование карточной колоды, но есть и другие применения — например, случайная сортировка списка вопросов.

Для решения этой задачи пригодится метод

rand
из модуля Kernel. Ниже показан один из возможных способов:

class Array

 def randomize

self.sort_by { rand } # Сортировать по ключу, являющемуся

 end # случайным числом.

 def randomize!

self.replace(self.randomize)

 end

end

x = [1, 2, 3, 4, 5]

y = x.randomize # [3, 2, 4, 1, 5]

x.randomize! # x равно [3, 5, 4, 2]

Из-за

самой природы сортировки, вероятно, вносится некоторое статистическое смещение. Но обычно это не играет роли.

Выбрать случайный элемент массива (не запрещая дубликатов) можно так:

class Array

 def pick_random

self[rand(self.length)]

 end

end

Наконец, не стоит забывать, что метод

rand
позволяет сгенерировать предсказуемую последовательность (например, для тестирования), если затравить алгоритм известным значением с помощью метода
srand
(см. раздел 5.28).

8.1.11. Многомерные массивы

Если для численного анализа вам нужны многомерные массивы, то в архиве приложений Ruby есть прекрасная библиотека

NArray
, которую написал Масахиро Танака (Masahiro Tanaka). Если необходим аппарат для работы с матрицами, обратитесь к стандартной библиотеке matrix.rb, которая была упомянута в разделе 5.10.

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

[]
и
[]=
для отображения элементов на вложенный массив. Представленный класс
Array3
обеспечивает рудиментарные операции с трехмерными массивами, но он далеко не полон:

class Array3

 def initialize

@store = [[[]]]

 end

 def [](a,b,c)

if @store[a]==nil ||

@store[a][b]==nil ||

@store[a][b][c]==nil

return nil

else

return @store[a][b][c]

end

 end

 def []=(a,b,c,x)

@store[a] = [[]] if @store[a]==nil

@store[a][b] = [] if @store[a][b]==nil

@store[a][b][с] = x

 end

end

x = Array3.new

x[0,0,0] = 5

x[0,0,1] = 6

x[1,2,31 = 99

puts x[1,2,3]

Единственное, чего мы реально добились, — так это удобного использования запятой в обозначении

[x,y,z]
вместо употребляемой в языке С нотации
[x][у][z]
. Если C-подобная нотация вас устраивает, можете просто воспользоваться вложенными массивами Ruby. Еще одно мелкое достоинство — предотвращение ситуации, когда объектом, от имени которого вызывается оператор
[]
, оказывается
nil
.

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

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

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

Архонт

Прокофьев Роман Юрьевич
5. Стеллар
Фантастика:
боевая фантастика
рпг
7.80
рейтинг книги
Архонт

Мастер 6

Чащин Валерий
6. Мастер
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер 6

Мачеха Золушки - попаданка

Максонова Мария
Фантастика:
попаданцы
сказочная фантастика
фэнтези
5.00
рейтинг книги
Мачеха Золушки - попаданка

Точка Бифуркации IX

Смит Дейлор
9. ТБ
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Точка Бифуркации IX

Стражи душ

Кас Маркус
4. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Стражи душ

Старый, но крепкий 5

Крынов Макс
5. Культивация без насилия
Фантастика:
рпг
аниме
уся
фэнтези
5.00
рейтинг книги
Старый, но крепкий 5

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

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

Первый среди равных. Книга II

Бор Жорж
2. Первый среди Равных
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Первый среди равных. Книга II

Точка Бифуркации XII

Смит Дейлор
12. ТБ
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации XII

Законы Рода. Том 3

Андрей Мельник
3. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 3

Бракованная невеста. Академия драконов

Милославская Анастасия
Фантастика:
фэнтези
сказочная фантастика
5.00
рейтинг книги
Бракованная невеста. Академия драконов

Великий и Ужасный - 2

Капба Евгений Адгурович
2. Великий и Ужасный
Фантастика:
киберпанк
городское фэнтези
попаданцы
5.00
рейтинг книги
Великий и Ужасный - 2

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

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10