Uploaded by Алекс Орлов

Laboratornaya rabot 1 Obrabotka spiskov na yazyke LISP

advertisement
1
Лабораторная работа №1
Обработка списков на языке ЛИСП
Цель работы: Изучить среду программирования Allegro CL Lite 3.0.1. Закрепить
теоретические сведения о базовых функциях языка Lisp: арифметические вычисления,
обработка списков, рекурсивные вычисления, создание пользовательских функций.
Задание:
1. Выбрать индивидуальный вариант из таблицы 1 согласно номеру в журнале
студента.
2. Согласно варианту реализовать на языке Lisp пользовательскую функцию по
рекурсивной обработке списка.
3. Протестировать программу.
Таблица 1 - Варианты заданий.
Номер
студента
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
Запрограммировать алгоритм:
Поиск числа в массиве целых чисел.
Поиск буквы в строковом массиве.
Сумма ряда целых чисел.
Произведение ряда целых чисел.
Уменьшить каждый элемент ряда целых чисел на фиксированное значение.
Увеличить каждый элемент ряда целых чисел на фиксированное значение.
Разделить каждый элемент ряда целых чисел на фиксированное значение.
Сложить поэлементно два массива и записать в память результат.
Умножить поэлементно два массива и записать в память результат.
Заменить в строковом массиве элемент, соответствующий шаблону, на
новый.
Поиск числа в массиве целых чисел.
Поиск буквы в строковом массиве.
Сумма ряда целых чисел.
Произведение ряда целых чисел.
Уменьшить каждый элемент ряда целых чисел на фиксированное значение.
Увеличить каждый элемент ряда целых чисел на фиксированное значение.
Разделить каждый элемент ряда целых чисел на фиксированное значение.
Сложить поэлементно два массива и записать в память результат.
Умножить поэлементно два массива и записать в память результат.
Заменить в строковом массиве элемент, соответствующий шаблону, на
новый.
Поиск числа в массиве целых чисел.
Поиск буквы в строковом массиве.
Сумма ряда целых чисел.
Произведение ряда целых чисел.
Уменьшить каждый элемент ряда целых чисел на фиксированное значение.
Примечание. Исходные данные сформировать произвольно. Длина массивов не менее 10
элементов.
2
Оформление отчета:
1. Титульный лист, текст задания, массивы данных.
2. Блок схема алгоритма. Листинг программы, с комментариями каждой инструкции.
3. Экранные формы.
4. Выводы.
Теоретические сведения
Пример задание. Запрограммировать алгоритм: Поиск буквы в строковом массиве.
Массив данных: a b c h j k v w z o
Листинг
(defun f (x y) //Объявление функции
(if (eql y nil) //Конец массива
'Not_found //Элемент не найден
(if (eql x (car y))
//Проверка первого элемента
'Found //Элемент найден
(f x (cdr y))))) //Рекурсивный вызов функции без первого элемента массива
(f 'c '(a b c h j k v w z o)) //Вызов функции
Блок-схема
Экранная форма
3
Примеры решений по обработке списков
Список, в котором нет ни одного элемента, называется пустым
списком и обозначается "( )" или символом 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)
4
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)) (openskob (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)))
5
(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))))
Рисунок 1 – Листинг функции Find-max
Функция Find-max (рисунок 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 – Листинг функции Sum-minus
Функция Sum-minus (рисунок 2) вычисляет сумму отрицательных чисел в
списке.
> (sum-minus '(2 (-1 5 -2) 6))
-3
Download