Использование define
для введения новых обозначений не всегда удобно. Часто возникает необходимость введения обозначений, действующих только внутри некоторого выражения. Для этого используется специальная форма let
:
(let список_обозначений выражение_1 выражение_2 ... выражение_n)
список обозначений = [(название_1 значение_1) (название_2 значение_2) ... (название_m значение_m)]
Эта форма вычисляет по очереди выражение_1
, выражение_2
, и т.д., в рамках которых допустимо использовать введённые обозначения. Значением всей формы является значение последнего выражения в ней. Напоминаем, что квадратные скобки стоят только для повышения читаемости (и поддерживаются, к сожалению, не всеми реализациями языка Scheme).
Пример использования:
(define (print-sum)
(display "Введите пару чисел: ")
(let [(a (read))
(b (read))]
(display a) (display " + ") (display b) (display " = ") (display (+ a b))
(newline)))
Массивом называется способ хранения данных, обладающий следующими особенностями:
каждой единице данных сопоставляется номер из некоторого непрерывного диапазона целых чисел;
по этому номеру можно «быстро» получать доступ к единице данных с этим номером.
Под «быстро» понимается, что время доступа (в некотором приближении) не зависит от количества хранимых данных (или от порядкового номера).
Традиционные списки в языке Scheme обладают первым свойством (каждому элементу можно сопоставить порядковый номер), но не обладают вторым: для того, чтобы получить доступ, например, к последнему элементу, нужно пройти весь список с начала до конца.
Массивы в Scheme называются словом vector
. Создать массив можно одним из двух способов:
(make-vector длина начальное_значение) ;; задав форму
(vector элемент_1 элемент_2 ... элемент_n) ;; задав элементы
Нумерация элементов массива начинается с нуля. Узнать количество хранимых элементов можно функцией vector-length
. Обратиться к указанному элементу можно так:
(vector-ref вектор номер) ;; получение текущего значения
(vector-set! вектор номер значение) ;; сохранение в вектор заданного значения
Напишите функцию vector-copy
, возвращающую копию поданного ей на вход массива.
Напишите функцию vector-resize
, создающую новый массив заданного размера, начало которого совпадает с началом указанного массива:
(vector-resize (vector 1 2 3) 2) ;; новый вектор: #(1 2)
(vector-resize (vector 1 2 3) 4) ;; новый вектор: #(1 2 3 что-угодно)
Напишите функцию vector-maximum
, находящую максимальное число в массиве.
Напишите функцию vector-map
, применяющую заданную функцию к каждому элементу массива и создающую новый массив из этих значений.
Напишите функцию vector-map!
, заменяющую каждый элемент массива на результат применения к нему заданной функции.
Напишите функцию vector-reduce
, осуществляющую левую свёртку массива (ту, что foldl).
Напишите функцию make-grid
, создающую «двухмерный массив» указанных размеров. Реализуйте следующие операции:
(grid-width g) ;; первое измерение массива g
(grid-height g) ;; второе измерение массива g
(grid-ref g i j) ;; элемент массива g с координатами i,j
(grid-set! g i j x) ;; сохранение в элемент массива g с координатами i,j значения x
Для реализации двухмерного массива вы можете использовать как «массив массивов», так и одномерный массив с пересчётом координат.
@ 2016 arbrk1, all rights reversed