|
Здравствуйте! Записался на ваш курс, но не понимаю как произвести оплату. Надо ли писать заявление и, если да, то куда отправлять? как я получу диплом о профессиональной переподготовке? |
Отображения и функционалы
Функционалы - общее понятие
Рассмотрим технику использования функционалов на упражнениях с числами и покажем, как от простых задач перейти к более сложным.
Для каждого числа из заданного списка получить следующее за ним число и все результаты собрать в список1Здесь и далее, следуя CLISP, (COND NIL) = NIL, т.е. допускается отсутствие предиката со значение "истина".
(DEFUN next (xl)
;; Следующие числа*)
(COND ; пока список не пуст
(x (CONS (1+ (CAR xl)) ; прибавляем 1 к его "голове"
(next (CDR xl)) ; и переходим к остальным,
) ) ) ) ; собирая результаты в список
(next '(1 2 5)) ; = (2 3 6)
4.1.
Построить список из <голов> элементов списка
(DEFUN 1st (xl)
; "головы" элементов = CAR
(COND ; пока список не пуст
(xl (CONS (caar xl); выбираем CAR от его головы
(1st (CDR xl)) ; и переходим к остальным,
) ) ) ) ; собирая результаты в список
(1st '((один два)(one two)(1 2)) ) ; = (один one 1)
4.2.
Выяснить длины элементов списка
(DEFUN lens (xl) ; Длины элементов
(COND ; Пока список не пуст
(xl (CONS (length (CAR xl))
; вычисляем длину его головы
(lens (CDR xl)); и переходим к остальным,
) ) ) ) ; собирая результаты в список
(lens '((1 2) () (a b c d) (1(a b c d)3)) )
; = (2 0 4 3)
4.3.
Внешние отличия в записи этих трех функций малосущественны, что позволяет ввести более общую функцию MAP-EL, в определении которой имена "CAR", "1+" и "LENGTH" могут быть заданы как значения параметра fn:
(DEFUN map-el(fn xl)
; Поэлементное преобразование XL с помощью функции FN
(COND ; Пока XL не пуст
(xl (CONS (FUNCALL fn (car xl))
; применяем FN как функцию к голове XL**)
(map-el fn (CDR xl))
; и переходим к остальным,
) ) ) ) ; собирая результаты в списокЭффект функций NEXT, 1ST и LENS можно получить выражениями:
(map-el #'1+ xl) ; Следующие числа:
(map-el #'CAR xl) ; "головы" элементов = CAR
(map-el #'length xl) ; Длины элементов
(map-el #'1+'(1 2 5)) ; = (2 3 6)
(map-el #'CAR'((один два)(one two)(1 2)) )
; = (один one 1)
(map-el #'length'((1 2)()(a b c d)(1(a b c d)3)) )
; = (2 0 4 3) соответственно.Примечание. #’x – эквивалент ( FUNCTION x ), что является представлением функции в качестве аргумента.
Все три примера можно решить с помощью таких определяющих выражений:
(DEFUN next(xl) (map-el #'1+ xl)) ; Очередные числа: (DEFUN 1st(xl) (map-el #'CAR xl)) ; "головы" элементов = CAR (DEFUN lens(xl) (map-el #'length xl)) ; Длины элементов
Эти определения функций формально эквивалентны ранее приведенным - они сохраняют отношение между аргументами и результатами. Параметром функционала может быть любая вспомогательная функция.
Пусть дана вспомогательная функция sqw, возводящая числа в квадрат
(DEFUN sqw (x)(* x x)) ; Возведение числа в квадрат (sqw 3) ; = 94.4.
Построить список квадратов чисел, используя функцию sqw:
(DEFUN sqware (xl)
; Возведение списка чисел в квадрат
(COND ; Пока аргумент не пуст,
(xl (CONS (sqw (CAR xl))
; применяем sqw к его голове
(sqware(CDR xl))
; и переходим к остальным,
) ) ) ) ; собирая результаты в список
(sqware'(1 2 5 7)) ; = (1 4 25 49 )Можно использовать map-el:
(DEFUN sqware (xl) (map-el #'sqw xl))
Ниже приведено определение функции SQWARE- без вспомогательной функции, выполняющее умножение непосредственно. Оно влечет за собой двойное вычисление (CAR xl), т.е. такая техника не вполне эффективна:
(DEFUN sqware- (xl)
(COND
(xl (cons (* (CAR xl) (car xl) )
; квадрат "головы" списка
; "голову" вычислять приходится дважды
(sqware- (CDR xl))
) ) ) )Пусть дана вспомогательная функция TUPLE, превращающая любое данное в пару:
(DEFUN tuple (x) (CONS x x)) (tuple 3) ; = (3 . 3) (tuple 'a) ; = (a . a) (tuple '(Ха)) ; = ((Ха) . (Ха)) = ((Ха) Ха) ; - это одно и то же!4.5.
Чтобы преобразовать элементы списка с помощью такой функции, пишем сразу:
(DEFUN duble (xl) (map-el #'tuple xl))
; дублирование элементов
(duble '(1(a)())) ; = ((1 . 1)((a)a)(()))Немногим сложнее организовать покомпонентную обработку двух списков.
Построить ассоциативный список, т.е. список пар из имен и соответствующих им значений, по заданным спискам имен и их значений:
(DEFUN pairl (al vl) ; Ассоциативный список
(COND ; Пока al не пуст,
(al (CONS (CONS (CAR al) (CAR vl))
; пары из <голов>.
(pairl (CDR al) (CDR vl))
; Если vl исчерпается,
; то CDR будет давать NIL
) ) ) )
(pair '(один два two three) '(1 2 два три))
; = ((один . 1)(два . 2)(two . два)(three . три))
4.6.
Определить функцию покомпонентной обработки двух списков с помощью заданной функции FN:
(DEFUN map-comp (fn al vl)
; fn покомпонентно применить
; к соотвественным элементам al и vl
(COND
(al (CONS (FUNCALL fn (CAR al) (CAR vl))
; Вызов данного fn как функции
(map-comp (CDR al) (CDR vl))
) ) ) )
4.7.
Теперь покомпонентные действия над векторами, представленными с помощью списков, полностью в наших руках. Вот списки и сумм, и произведений, и пар, и результатов проверки на совпадение:
(map-comp #'+'(1 2 3) '(4 6 9))
; = (5 8 12) Суммы
(map-comp #'*'(1 2 3) '(4 6 9))
; = (4 12 27) Произведения
(map-comp #'CONS'(1 2 3) '(4 6 9))
; = ((1 . 4) (2 . 6) (3 . 9)) Пары
(map-comp #'EQ'(4 2 3) '(4 6 9))
; = (T NIL NIL) СравненияДостаточно уяснить, что надо делать с элементами списка, остальное довершит функционал MAP-COMP, отображающий этот список в список результатов заданной функции.
Для заданного списка вычислим ряд его атрибутов, а именно - длина, первый элемент, остальные элементы списка без первого.
(DEFUN mapf (fl el)
(COND ; Пока первый аргумент не пуст,
(fl (CONS (FUNCALL (CAR fl) el)
; применяем очередную функцию
; ко второму аргументу
(mapf (CDR fl) el)
; и переходим к остальным функциям,
) ) ) ) ; собирая их результаты в общий
; список
(mapf '(length CAR CDR) '(a b c d))
; = (4 a (b c d))
4.8.
Композициями таких функционалов можно применять серии функций к списку общих аргументов или к параллельно заданной последовательности списков их аргументов. Естественно, и серии, и последовательности представляются списками.
