Задания для самостоятельной работы
1) Вычислить N!.
2) Вычислить n-ый член последовательности Фибоначчи.
3) Вывести все числа от n до 1.
4) Вывести все числа от 1 до n.
5) Вычислить сумму чисел от 1 до n.
6) Определите xn, n>0.
7) Определите 2n, n>0.
8) Определите N5, n>0.
9) Вычислите сумму четных чисел от 1 до n.
10) Вычислите сумму квадратов нечетных чисел от 1 до n.
11) Вычислите сумму ak, где ak=1/(1+k).
12) Вычислить .
13) Вычислить .
14) Определите корень уравнения методом половинного деления.
15) Найти наибольший общий делитель двух чисел, трех чисел.
16) Определить число сочетаний .
17) Вычислить N!+(N-1)!+...+2!+1!.
18) Вычислить количество четных элементов на заданном интервале.
19) Перевести число из десятичной системы счисления в систему с основанием N, где N<10, N>1.
Рекомендуемая литература
1. Стобо Д.Ж. Язык программирования Пролог: Пер. с англ.- М.- Радио и связь, 1993.-368 с.:ил.
2. Ин Ц., Соломон Д. Использование Турбо-Пролога: Пер. с англ.-М.:Мир, 1993.-608 с.,ил.
3. Информатика:Учеб.пособие для студ.пед.вузов/А.В.Могилев, Н.И.Пак, Е.К.Хеннер;Под ред. Е.К.Хеннера.-3-е изд., перераб. и доп.-М.:Издательский центр “Академия”, 2004.-848 с.
Лабораторная работа №4. Применение рекурсии для обработки списков
Пример 1. Определить количество элементов в списке.
Количество элементов пустого списка равно 0, в противном случае, нужно определить количество элементов в хвосте и найденное значение увеличить на единицу.
Программа 18. Определение длины списка
Domains
list = integer*
Predicates
length_of(list, integer)
Clauses
length_of([], 0):-!.
length_of([_|T], N) :- length_of(T, N1),N = N1 + 1.
?- length ([2, 12, 45]), X).
Ответ: Х=3.
Пример 2. Найти сумму элементов в списке.
Сумма элементов пустого списка равна 0, сумма элементов непустого списка определяется сложением головы списка с суммой элементов хвоста.
sum ([], 0):-!.
sum ([H|T], S) :- sum (T, S1), S = S1+H.
?-sum ([2, 12, 45]), X).
Ответ: Х=59
Пример 3. Определить принадлежность элемента списку.
Программа 19. Определение принадлежности элемента списку
Domains
type=integer
list=type*
Predicates
member(type,list)
Clauses
member(H,[H|_]):-!.
member(H,[_|T]):-member(H,T).
Запрос:
member (4,[1,3,4,9]).
Ответ: Yes.
Данная программа имеет очень простой декларативный смысл: элемент принадлежит списку, если он является его головой или принадлежит хвосту списка.
Пример 4.Объединить два списка.
Эту задачу можно описать с помощью следующих предикатов:
а) если к пустому списку [] добавить список Р, то в результате получится Р;
б) чтобы добавить список Р к концу списка [X|Y], нужно Р добавить к хвосту Y и затем присоединить к голове Х, при этом получается список [Х|Т].
Программа 20. Объединение двух списков
Domains
type=integer
list=type*
Predicates
append(list,list,list)
Clauses
append([],L,L):-!.
append([H|T],P,[H|Y]):-append(T,P,Y).
? append ([3, 5, 7], [12,5],K).
Ответ: К=[3,5,7,12,5]
Процедуру append можно использовать:
1) для разбиения списка на подсписки:
? append (X,Y,[1,2])
Ответ: X=[ ]Y=[l,2]
X=[l] Y=[2]
X=[l,2] Y=[]
2) Для вывода последнего элемента списка:
last(X,L):-append(_,[X],L)
Пример 5. Удаление элементов из списка.
Первый аргумент указывает удаляемый элемент, второй аргумент - исходный список и третий - список-результат.
Программа 21. Удаление элементов из списка
Domains
type=integer
list=type*
Predicates
delete(type,list,list)
Clauses
delete(X,[X|T],T):-!.
delete(X,[Y|T],[Y|T1]):-delete(X,T,T1).
Смысл: результат удаления произвольного элемента из пустого списка, есть пустой список, если удаляемый элемент совпадает с головой списка, то результатом программы является хвост списка, иначе удаление производится из хвоста списка.
Данная программа удаляет первое вхождение элемента в список. Знак отсечения "!" в конце правила предотвращает последующий поиск и вывод лишних вариантов ответов после выполнения ограничительного факта.
Для удаления всех вхождений элемента Х программу надо дополнить:
delete(_, [], []) :-!.
delete(X, [X | T], W) :- delete(X, T, W),!.
delete(X, [Y | T], [Y|W]) :- delete(X, T, W) .
Смысл программы таков: пока список не пуст, удалить элемент, если он совпадает с головой списка, а затем удалять его из хвоста, иначе надо сразу удалять элемент из хвоста.
Пример 6. Индексация элементов списка.
Определить номер элемента X.
nomer([X |_], 1, X):-!.
nomer ([_| T], N, X) :- nomer(T, N1, X), N=N1+1.
Пример 7. Вывести максимальный элемент.
max ( [X] , X) .
max ([X | T], X) :- max (T, M), X>M, !.
max ( [_| T] , M) :- max (T, M) .
Смысл программы: если в списке один элемент - он и является максимальным, если более одного, то это голова списка, если она больше максимального элемента хвоста, или максимальный элемент хвоста.
Пример 8. Обращение списка.
Обратить список из одного элемента - означает оставить список без изменения. Обратить более длинный список - обратить его хвост, а потом справа добавить к нему голову исходного списка.
reverse([X], [X]):-!.
reverse ([X | T], Z) :- reverse (T, W), append(W, [X], Z).
Пример 9. Иногда бывает полезно представить в виде списка информацию, содержащуюся в известных фактах. В Прологе для этой цели служит предикат findall. Полный формат предиката: findall(Переменная, Атом, Список), здесь Атом- отношения, которое определяет список элементов, конкретизирующих переменную в качестве аргумента предиката атом. Рассмотрим предикат на примере вычисления общей суммы окладов служащих
Прорамма 22. Сумма окладов служащих
Domains
i=integer
sp=i*
fam,im,dolgnost=symbol
Predicates
sum(sp,i)
go
spisok(fam,im,dolgnost,i)
Clauses
sum([],0):-!.
sum([H|T],S):-sum(T,S1),S=S1+H.
spisok(ivanov, ivan, slesar,400).
spisok(petrov, petr,tokar,200).
spisok(sidorov, denis,plotnik,100).
go:-findall(X,spisok(_,_,_,X),L), sum(L,A).
Поиск по сайту:
|