Душкин Роман Викторович darkus@yandex ru Москва, 2001 лекция
Вид материала | Лекция |
СодержаниеПример 5. Операция prefix. Пример 6. Функция определения длины списка Length. Пример 7. Функция слияния двух списков Append. Ответы для самопроверки |
- Евгений Викторович Петров, 12.9kb.
- Демонстрационная версия рабочей программы по ен. Ф. 05 «Биология» для специальности, 34.32kb.
- Роман Москва «Детская литература», 3628.68kb.
- Фалалеев Роман Викторович руководитель Делового центра предпринимательской активности., 16.14kb.
- Прогнозирование потребности в педагогических кадрах в регионе фролов Юрий Викторович, 113.56kb.
- Сорокин Павел Викторович. Предмет: история Класс: 10 программа, 999.87kb.
- 2001 Утвержден Минтопэнерго России, 1942.6kb.
- 117042, г. Москва, ул. Адмирала Лазарева, д. 52, корп. 3; тел. +7(495) 500-91-58;, 1396.81kb.
- Пособие для логопедов Москва 2001 бек 74. 3 Удк 371. 927, 514.36kb.
- Сергей Викторович Тютин* Это очень важная лекция, 119.72kb.
Примеры
Пример 5. Операция prefix.
Для начала необходимо рассмотреть более подробно работу операции prefix. Пояснение работы будет проведено на трёх более или менее общих примерах:
1. prefix (a1, a2) = a1 : a2 (при этом результат не является элементом List_str (A)).
2. prefix (a1, [b1, b2]) = [a1, b1, b2]
3. prefix ([a1, a2], [b1, b2]) = [[a1, a2], b1, b2]
Пример 6. Функция определения длины списка Length.
Перед тем, как собственно начать реализовывать функцию Length, необходимо понять, что она должна возвращать. Понятийное определение результата функции Length может звучать как «количество элементов в списке, который передан функции в качестве параметра». Здесь возникает два случая — функции передан пустой список и функции передан непустой список. С первым случаем все ясно — результат должен быть нулевым. Во втором случае задачу можно разбить на две подзадачи, путем разделения переданного списка на голову и хвост при помощи операций head и tail.
Осмысленно, что операция head возвращает первый элемент списка, а операция tail возвращает список из оставщихся элементов. Пусть известна длина списка, полученного при помощи операции tail, тогда длина исходного списка будет равна известной длина, увеличенной на единицу. В этом случае можно легко записать определение самой функции Length:
Length ([]) = 0
Length (L) = 1 + Length (tail (L))
Пример 7. Функция слияния двух списков Append.
Реализовать функцию слияния (или сцепления) списков можно многими способами. Первое, что приходит в голову — деструктивное присваивание. Т.е. заменить указатель на [] в конце первого списка на указатель на голову второго списка и тем самым получить результат в первом списке. Однако здесь изменяется сам первый список. Такие приёмы запрещены в функциональном программировании (хотя, в очередной раз необходимо заметить, что в некоторых функциональных языках всё-таки есть такая возможность).
Второй способ состоит в копировании верхнего уровня первого списка и помещении в последний указатель копии ссылку на первый элемент второго списка. Этот способ хорош с точки зрения деструктивности (не выполняет деструктивных и побочных действий), однако требудет дополнительных затрат памяти и времени.
Append ([], L2) = L2
Append (L1, L2) = prefix (head (L1), Append (tail (L1), L2))
Последний пример показывает, как при помощи постепенного конструирования можно построить новый список, который равен сцепке двух заданных.
Упражнения
- Построить функции, вычисляющие N-ый элемент следующих рядов:
- an = xn
- an = i = 1,n i
- an = j = 1,n (i = 1,j i)
- an = i = 1,p n-i
- an = en = i = 0, (ni / i!)
- an = xn
- Объяснить результаты операции prefix, показанные в примере 5. Для объяснения можно воспользоваться графическим методом.
- Объяснить результат работы функции Append (пример 7). Пояснить, почему функция не является деструктивной.
- Построить функции, работающие со списками:
- GetN — функция вычленения N-ого элемента из заданного списка.
- ListSumm — функция сложения элементов двух списков. Возвращает список, составленный из сумм элементов списков-параметров. Учесть, что переданные списки могут быть разной длины.
- OddEven — функция перестановки местами соседних чётных и нечётных элементов в заданном списке.
- Reverse — функция, обращающая список (первый элемент списка становится последним, второй — предпоследним, и так далее до последнего элемента).
- Map — функция применения другой переданной в качестве параметра функции ко всем элементам заданного списка.
- GetN — функция вычленения N-ого элемента из заданного списка.
Ответы для самопроверки
Большинство ответов для самопроверки представляют собой лишь одни из возможных вариантов (в большинстве случаев наиболее интуитивные).
- Функции, вычисляющие N-ый элемент рядов:
- Power:
Power (X, 0) = 1
Power (X, N) = X * Power (X, N – 1)
- Summ_T:
Summ_T (1) = 1
Summ_T (N) = N + Summ_T (N – 1)
- Summ_P:
Summ_P (1) = 1
Summ_P (N) = Summ_T (N) + Summ_P (N – 1)
- Summ_Power:
Summ_Power (N, 0) = 1
Summ_Power (N, P) = (1 / Power (N, P)) + Summ_Power (N, P – 1)
- Exponent:
Exponent (N, 0) = 1
Exponent (N, P) = (Power (N, P) / Factorial (P)) + Exponent (N, P – 1)
Factorial (0) = 1
Factorial (N) = N * Factorial (N – 1)
- Объяснение работы операции prefix можно легко провести в три приёма (равно так же, как и приведено в примере). Для того чтобы не загромождать объяснения, здесь наряду с функциональной записью операции prefix также используется инфиксная запись посредством символа двоеточия.
- Первый пример работы операции — определение самой операции. Рассматривать его нет смысла, ибо операция prefix определяется именно таким образом.
- prefix (a1, [b1, b2]) = prefix (a1, b1 : (b2 : [])) = a1 : (b1 : (b2 : [])) = [a1, b1, b2]
(Эти преобразование проведены по определению списка).
- prefix ([a1, a2], [b1, b2]) = prefix ([a1, a2], b1 : (b2 : [])) = ([a1, a2]) : (b1 : (b2 : [])) =
= [[a1, a2], b1, b2].
- Первый пример работы операции — определение самой операции. Рассматривать его нет смысла, ибо операция prefix определяется именно таким образом.
- В качестве примера работы функции Append рассмотрим сцепку двух списков, каждый из которых состоит из двух элементов: [a, b] и [c, d]. Опять же для того, чтобы не загромождать объяснение, для записи операции prefix используется инфиксная форма. Для более полного понимания приведенного объяснения необходимо помнить определение списка.
Append ([a, b], [c, d]) = a : Append ([b], [c, d]) = a : (b : Append ([], [c, d])) =
= a : (b : ([c, d])) = a : (b : (c : (d : []))) = [a, b, c, d].
- Функции, работающие со списками:
- GetN:
GetN (N, []) = _
GetN (1, H:T) = H
GetN (N, H:T) = GetN (N – 1, T)
- ListSumm:
ListSumm ([], L) = L
ListSumm (L, []) = L
ListSumm (H1:T1, H2:T2) = prefix ((H1 + H2), ListSumm (T1, T2))
- OddEven:
OddEven ([]) = []
OddEven ([X]) = [X]
OddEven (H1:[H2:T]) = prefix (prefix (H2, H1), OddEven (T))
- Reverse:
Reverse ([]) = []
Reverse (H:T) = Append (Reverse (T), [H])
- Map:
Map (F, []) = []
Map (F, H:T) = prefix (F (H), Map (F, T))