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

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

Жанры

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

а = %w[Elrond Galadriel Aragorn Saruman Legolas]

b = a.min # "Aragorn"

с = a.max # "Saruman"

d = a.min {|x,y| x.reverse <=> y.reverse} # "Elrond"

e = a.max {|x,y| x.reverse <=> y.reverse} # "Legolas"

Чтобы найти индекс минимального или максимального элемента (в предположении, что такой элемент один), применяется метод

index
:

# Продолжение предыдущего примера...

i = a.index a.min # 2

j = a.index a.max # 3

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

8.1.7. Специализированные функции индексирования

Для отображения индексов на элементы массива интерпретатор языка пользуется функцией индексирования. Поскольку методы доступа к элементам массива можно переопределять, мы можем реализовать любой способ индексирования.

Например, ниже реализован массив, в котором индексы начинаются с 1, а не с нуля:

class Array2 < Array

 def [] (index)

if index>0

super(index-1)

else

raise IndexError

end

 end

 def []=(index,obj)

if index>0

super(index-1,obj)

else

raise IndexError

end

 end

end

x = Array2.new

x[1]=5

x[2]=3

x[0]=1 # Ошибка.

x[-1]=1 # Ошибка.

Отметим, что отрицательные индексы (от конца массива) здесь запрещены. Имейте в виду, что в реальной задаче придется внести и другие изменения, например переопределить метод

slice
и пр. Но общую идею вы поняли.

Аналогичный подход можно применить для реализации многомерных массивов (мы еще вернемся к ним в разделе 8.1.11).

Можно также реализовать нечто вроде треугольной матрицы, как показано ниже. Это частный случай двумерного массива, в котором элемент в позиции

x,y
совпадает с элементом в позиции
y,x
(поэтому хранить можно только один). Иногда это бывает полезно, например для хранения неориентированного графа (как мы покажем ближе к концу главы).

class TriMatrix

 def initialize

@store = []

 end

 def [](x,y)

if x > у

index = (x*x+x)/2 + y

@store[index]

else

raise IndexError

end

 end

 def []=(x,y,v)

if x > y

index = (x*x+x)/2 + y

@store[index] = v

else

raise IndexError

end

 end

end

t = TriMatrix.new

t[3,2] = 1

puts t[3,2] # 1

puts t[2,3] # IndexError

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

Можно было унаследовать классу

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

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

8.1.8. Реализация разреженной матрицы

Иногда бывает нужен массив, в котором определена лишь небольшая часть элементов, а остальные не определены вовсе или (даже чаще) равны 0. Подобная разреженная матрица потребляет так много памяти зря, что были найдены способы более изощренной ее реализации.

Конечно, в большинстве случаев обычного массива Ruby вполне достаточно, так как в современных компьютерах недостатка памяти не ощущается. Элемент, которому не присвоено значение, будет равен

nil
, так что на его хранение расходуется всего несколько байтов.

С другой стороны, присваивание значения элементу массива, лежащему за текущей правой границей, приводит к созданию всех промежуточных элементов, причем они получают значение

nil
. Например, если определены элементы от 0 до 9 и затем производится присваивание элементу 1000, то создаются также элементы с индексами от 10 до 999, равные
nil
. Если это неприемлемо, надо поискать альтернативу.

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

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

Я все еще граф. Книга IX

Дрейк Сириус
9. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я все еще граф. Книга IX

Черный Маг Императора 18

Герда Александр
18. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 18

Барон диктует правила

Ренгач Евгений
4. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон диктует правила

Развод с драконом. Отвергнутая целительница

Шашкова Алена
Фантастика:
фэнтези
4.75
рейтинг книги
Развод с драконом. Отвергнутая целительница

Отморозок 3

Поповский Андрей Владимирович
3. Отморозок
Фантастика:
попаданцы
5.00
рейтинг книги
Отморозок 3

Стеллар. Трибут

Прокофьев Роман Юрьевич
2. Стеллар
Фантастика:
боевая фантастика
рпг
8.75
рейтинг книги
Стеллар. Трибут

Эпоха Опустошителя. Том II

Павлов Вел
2. Вечное Ристалище
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эпоха Опустошителя. Том II

Кодекс Охотника XXVIII

Винокуров Юрий
28. Кодекс Охотника
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Кодекс Охотника XXVIII

#Бояръ-Аниме. Газлайтер. Том 11

Володин Григорий Григорьевич
11. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 11

Тринадцатый IX

NikL
9. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
сказочная фантастика
5.00
рейтинг книги
Тринадцатый IX

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

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

Древесный маг Орловского княжества 9

Павлов Игорь Васильевич
9. Орловское княжество
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества 9

Я еще князь. Книга XX

Дрейк Сириус
20. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я еще князь. Книга XX

Двойник короля 11

Скабер Артемий
11. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 11