Выбрать элементы, не превосходящие среднее арифметическое списка

Главная Форумы Программирование Помощь с решением задач на Prolog Задачи на списки Выбрать элементы, не превосходящие среднее арифметическое списка

В этой теме 1 ответ, 2 участника, последнее обновление  Васильев Владимир Сергеевич 2 года/лет, 10 мес. назад.

  • Автор
    Сообщения
  • #1927

    questioner
    Участник

    Здравствуйте. Помогите пожалуйста написать программу на swi-prolog.
    Дан список. Найти средний элемент списка (среднее арифметическое) и сформировать новый список. В новый список поместить элементы из исходного, превосходящие по величине среднее арифметическое.
    Очень надеюсь на вашу помощь.

  • #1928

    Среднее арифметическое – это сумма, деленная на количество элементов. Сумму можно вычислить стандартными предикатом sum_list, количество – предикатом length. Если в вашем диалекте (например Turbo Prolog) нет таких встроенных предикатов – скопируйте их из статьи по обработке списков.

    Чтобы выбрать элементы, меньше заданного значения можно использовать стандартный предикат include(Predicate, SourceList, IncludeList). Первым аргументом он принимает функцию от одного аргумента, которая будет применена к каждому элементу исходного списка. В результирующий список попадут лишь те элементы, для которых выполнение предиката завершится успешно.

    select_less_average([], _Select):-!, fail.
    select_less_average(List, Select):-
        sumlist(List, Sum), length(List, Len),
        Average is Sum / Len,
        include(<(Average), List, Select).

    Первое правило обрабатывает отдельно случай с поданным на вход пустым списком. Это нужно, т.к. длина такого списка равна нулю, а значит при вычислении среднего арифметического программа попыталась бы произвести деление на ноль.
    В качестве предиката в функцию include передается оператор сравнения с подставленным первым аргументом. В результате подстановки одного операнда формируется новый оператор (частично вычисленный) с меньшим количеством аргументов, в котором вместо использования удаленного операнда подставлено конкретное значение. Такая техника называется каррированием или каррингом (currying).

    Если вы используете Turbo Prolog или Visual Prolog – то описанная техника не сработает, кроме того, в стандартной библиотеке этих языков нет функции include. Можно написать свою функцию:

    include_less([], _Pivot, []):-!.
    include_less([Head|Tail], Pivot, [Head|IncludeTail]):-
      Head < Pivot !, include_less(Tail, Pivot, IncludeTail).
    include_less([_Head|Tail], Pivot, IncludeTail):-
      include_less(Tail, Pivot, IncludeTail).

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

Для ответа в этой теме необходимо авторизоваться.