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

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

Жанры

Программирование на языке 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).

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

Звездная Кровь. Экзарх II

Рокотов Алексей
2. Экзарх
Старинная литература:
прочая старинная литература
5.00
рейтинг книги
Звездная Кровь. Экзарх II

Феодал

Громов Александр Николаевич
Фантастика:
социально-философская фантастика
7.94
рейтинг книги
Феодал

Хозяин Теней 5

Петров Максим Николаевич
5. Безбожник
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Хозяин Теней 5

Мл. сержант. Назад в СССР. Книга 3

Гаусс Максим
3. Второй шанс
Фантастика:
альтернативная история
6.40
рейтинг книги
Мл. сержант. Назад в СССР. Книга 3

Ким

Киплинг Редьярд Джозеф
Приключения:
исторические приключения
7.62
рейтинг книги
Ким

Лекарь Империи 15

Карелин Сергей Витальевич
15. Лекарь Империи
Фантастика:
городское фэнтези
аниме
фэнтези
попаданцы
6.80
рейтинг книги
Лекарь Империи 15

Родословная. Том 5

Ткачев Андрей Юрьевич
5. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Родословная. Том 5

Гром Раскатного. Том 3

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

Диверсант

Вайс Александр
2. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Диверсант

Путь Шедара

Кораблев Родион
4. Другая сторона
Фантастика:
боевая фантастика
6.83
рейтинг книги
Путь Шедара

Последний Паладин. Том 3

Саваровский Роман
3. Путь Паладина
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 3

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

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

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

Искатель 2

Шиленко Сергей
2. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 2