Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Вопросы с ответами ЯП.docx
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
231.17 Кб
Скачать

20) Обработка списков: суммирование, вычисление произведения элементов списка, поиск минимального и максимального элементов.

Сумму элементов списка.

Решение будет напоминать подсчет количества элементов списка. Отличаться они будут шагом рекурсии. При подсчете количества элементов нам было неважно, чему равен первый элемент списка, мы просто добавляли единицу к уже подсчитанному количеству элементов хвоста. При вычислении суммы нужно будет учесть значение головы списка.

Так как в пустом списке элементов нет, сумма элементов пустого списка равна нулю. Для вычисления суммы элементов непустого списка нужно к сумме элементов хвоста добавить первый элемент списка. Запишем эту идею:

sum([], 0). /* сумма элементов пустого списка равна

нулю */

sum([H|T], S) :–

sum(T, S_T), /* S_T — сумма элементов хвоста */

S = S_T + H. /* S — сумма элементов исходного

списка */

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

Еще один вариант данного предиката можно написать, используя накопитель. В нем будем хранить уже насчитанную сумму. Начинаем с пустым накопителем. Переходя от вычисления суммы непустого списка к вычислению суммы элементов его хвоста, будем добавлять первый элемент к уже насчитанной сумме. Когда элементы списка будут исчерпаны (список опустеет), передадим "накопленную" сумму в качестве результата в третий аргумент.

Запишем:

sum_list([],S,S). /* список стал пустым, значит

в накопителе — сумма элементов

списка */

sum_list([H|T],N,S) :–

N_T=H+N,

/* N_T — результат добавления к сумме,

находящейся в накопителе, первого

элемента списка */

sum_list(T,N_T,S).

/* вызываем предикат от хвоста T и N_T */

Если нам нужно вызвать предикат от двух аргументов, а не от трех, то можно добавить вспомогательный предикат:

sum2(L,S):–

sum_list(L,0,S).

Последний вариант, в отличие от первого, реализует хвостовую рекурсию.

Минимальный(максимальный) элемент списка.

Как обычно, наше решение будет рекурсивным. Но так как для пустого списка понятие минимального элемента не имеет смысла, базис рекурсии мы запишем не для пустого, а для одноэлементного списка. В одноэлементном списке, естественно, минимальным элементом будет тот самый единственный элемент списка ("при всем богатстве выбора другой альтернативы нет!").

Шаг рекурсии: найдем минимум из первого элемента списка и минимального элемента хвоста — это и будет минимальный элемент всего списка.

Оформим эти рассуждения:

min_list([X],X). /* единственный элемент одноэлементного

списка является минимальным элементом

списка */

min_list([H|T],M):–

min_list(T,M_T), /* M_T — минимальный элемент хвоста */

min(H,M_T,M). /* M — минимум из M_T и первого элемента

исходного списка */

Обратите внимание на то, что в правиле, позволяющем осуществить шаг рекурсии, использован предикат min, подобный предикату max, который был разобран нами в третьей лекции.

Слегка модифицировав предикат min_list (подставив в правило вместо предиката min предикат max и поменяв его название), получим предикат, находящий не минимальный, а максимальный элемент списка.