Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
дополнение1 к мет ФП 2012.doc
Скачиваний:
4
Добавлен:
13.11.2019
Размер:
152 Кб
Скачать
☆

2.4.2 Примеры решений по обработке списков

Список, в котором нет ни одного элемента, называется пустым списком и обозначается "( )" или символом NIL. NIL - это и список и атом одновременно. NIL обозначает кроме этого, в логических выражениях логическую константу "ложь" (false). Логическое "да" (true) задается символом "Т".

S-выражения, которые не надо вычислять, помечают для интерпретатора апострофом " ' ". Вместо апострофа можно использовать функцию QUOTE. QUOTE - специальная функция с одним аргументом, которая возвращает в качестве значения этот аргумент.

> (quote (+ 1 2))

(+ 1 2)

или

> ('(+ 1 2))

(+ 1 2)

Функция EVAL обеспечивает дополнительный вызов интерпретатора Лиспа. При этом вызов может производится внутри вычисляемого S-выражения. Функция EVAL позволяет снять блокировку QUOTE. Quote и eval действуют во взаимно противоположенных направлениях и аннулируют эффект друг друга.

> (eval (quote (+ 1 2)))

3

Функция SETQ связывает символ со значением, но не вычисляет значение первого аргумента. Буква q на блокировку.

> (setq m 2)

2

> m

2

> (setq lis '(a b c))

(a b c)

Функция CAR возвращает в качестве значения первый элемент списка, т.е. голову.

> (car lis)

a

Функция CDR применяется к спискам, причем ее значением является хвост списка, получаемый из исходного списка после удаления из него головы.

> (cdr '(a b c))

(b c)

Функция CONS строит новый список из своих аргументов. Причем первый аргумент становится головой второго аргумента, который обязательно является списком.

> (cons 'a '(b c))

(a b c)

Функция APPEND объединяет два и более списков в один. Причем она образует новый список, убирая скобки вокруг аргументов и помещая их в один список.

> (append '(a b c) '(c d))

(a b c c d)

Функцию можно определить самим и использовать как встроенную. Чтобы определить функцию, необходимо: дать имя функции, определить параметры функции, определить, что должна делать функция. Для задания новых функций в Лиспе используется специальная форма DEFUN: (defun < имя-функции > < параметры > < тело-функции >)

> (defun double (num) (* 2 num))

double

> (double 10)

20

СOND является основным средством организации разветвления вычислений: (COND (<проверка-n> <действие-n>)). Обычно в качестве последнего условия пишется t, соответствующее ему выражение будет вычисляться в тех случаях, когда ни одно другое условие не выполняется.

Рассмотрим пример: если число положительное – 1, иначе 0

> (defun f(x)

(cond

((plusp x) 1)

(t 0)

) )

f

> (f 100)

1

> (f -100)

0

Предикат NULL проверяет, является ли аргумент пустым списком.

> (null '( ))

T

Числовой предикат PLUSP проверяет, является ли число положительным.

> (plusp 4)

T

> (plusp -18)

NIL

Числовой предикат MINUSP проверяет, является ли число отрицательным.

> (minus -6)

T

Рассмотрим несколько функций работы со списками.

; приведение всех элементов списка к одному уровню иерархии

(defun open-skob (list1)

(cond

((null list1) nil)

((numberp (car list1))(cons (car list1)(open-skob (cdr list1))))

((listp (car list1)) (append (open-skob (car list1)) (open-skob (cdr list1))))

(t (open-skob (cdr list1)))

))

; поиск максимума

(defun max0 (list1 max)

(cond

((null list1) max)

((> (car list1) max) (max0 (cdr list1) (car list1)))

(t (max0 (cdr list1) max))

))

; удаление найденного максимума из списка

(defun del (max list1)

(cond

((null list1) nil)

((= max (car list1)) (del max (cdr list1)))

(t (cons (car list1) (del max (cdr list1))))

))

(defun del0 (list1)

(del (max0 list1 0) list1))

; нахождение 3 максимумов и вывод их в отдельный список

(defun find-max (list1 k list2)

(if (= k 3) list2

(find-max (del0 (open-skob list1)) (+ k 1) (cons (max0 (open-skob list1) 0) list2))))

Рисунок 2.1 – Листинг функции Find-max

Функция Find-max (рисунок 2.1) находит 3 максимальных числа в списке и выводит их в отдельный список.

> (setq list1 '((4 5) 6 (6 8 (3)) q1 (8 9 q 9)))

((4 5) 6 (6 8 (3)) Q1 (8 9 Q 9))

> (find-max list1 0 nil)

(6 8 9)

(defun sum-minus (x)

(cond

((null x) 0)

((listp (car x))(+ (sum-minus (car x))(sum-minus (cdr x))))

((minusp (car x)) (+ (car x)(sum-minus (cdr x))))

(t (sum-minus (cdr x)))

))

Рисунок 2.2 – Листинг функции Sum-minus

Функция Sum-minus (рисунок 2.2) вычисляет сумму отрицательных чисел в списке.

> (sum-minus '(2 (-1 5 -2) 6))

-3