Количество положительных элементов списка

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

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

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

    questioner
    Участник

    Нужно решение задачи на Turbo Prolog:

    Посчитать количество положительных элементов списка.

    Вывести на терминал исходный список и список положительных.

  • #2219

    Чтобы обрабатывать списки на Turbo Prolog необходимо объявить соответствующий тип данных в разделе domains:

    domains
      int_list = integer*

    По заданию требуется:

    • выводить список на экран;
    • считать количество положительных элементов;
    • вывести список положительных элементов

    Для вывода списка положительных элементов можно сформировать список таких чисел и вывести его используя уже написанную функцию. Все три функции должны быть описаны в разделе predicates:

    predicates
      print_list(int_list)
      list_count_positive(int_list, integer)
      positive_elements(int_list, int_list)

    В данном случае, функция list_count_positive принимает список целых чисел и возвращает целое число, а positive_elements – на основе списка формирует новый, содержащий только положительные (но тоже целые – integer) числа.

  • #2220

    Реализация функций размещается в разделе clauses.

      print_list([]):-
        nl, !.
      print_list([Head|Tail]):-
        write(Head), write(" "),
        print_list(Tail).

    Функция вывода элементов на экран состоит из двух правил:

    • первое сработает лишь если исходный список пуст ([]) – при этом функция выводит на экран пустую строку командой nl и запрещает поиск других решений (переход на второе правило) за счет выполнения отсечения (!);
    • если исходный список не пуст, то управление передается на второе правило. Исходный список разделяется на первый элемент и список остальных элементов ([Head|Tail]), первый элемент выводится на экран, выводится пробел, остальные элементы обрабатываются рекурсивно.
  • #2221

    Функция подсчета количества положительных элементов:

    1. возвращает ноль если исходный список пуст, при этом отсечением запрещается перебор других вариантов:
      list_count_positive([], 0):-!.
    2. разделяет список на первый элемент и остальные (голову и хвост). Выполняется сравнение первого элемента с нулем – если он положителен, то остальные элементы (Tail) обрабатываются рекурсивно (вычисляется количество положительных элементов в хвосте – TailCount). К результату обработки хвоста прибавляется единица (т.к. первый элемент положителен и его нужно учесть) – полученное значение возвращается:
        list_count_positive([Head|Tail], Count):-
          Head > 0, !, list_count_positive(Tail, TailCount),
          Count = TailCount + 1.

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

    3. Если первый элемент не положителен, то результат работы функции должен совпадать с результатом рекурсивной обработки хвоста списка. Список по прежнему необходимо разделять на голову и хвост, однако значение первого элемента не участвует в вычислении результата, поэтому переменная должна быть описана анонимной – перед ее именем ставится символ подчеркивания:
        list_count_positive([_Head|Tail], Count):-
          list_count_positive(Tail, Count).

  • #2222

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

    1. если исходный список пуст, то в нем нет положительных элементов, значит результат работы функции – пустой список (результат во втором аргументе):
      positive_elements([], []):-!.
    2. если первый элемент положителен, то его значение добавляется к результату рекурсивной обработки остальных элементов:
        positive_elements([Head|Tail], [Head|TailPositive]):-
          Head > 0, !, positive_elements(Tail, TailPositive).

      Тут сначала выполняется разделение исходного списка на голову и хвост (также как рассматривалось ранее), а затем с использованием точно такого эе синтаксиса – формирование результата из Head и TailPositive во втором аргументе функции. Т.е. операция [Head|TailPositive] будет выполнена последней и с ее помощью из значения первого элемента и списка TailPositive будет сформирован новый список.

    3. если первый элемент не является положительным – то добавлять его к результату не требуется, поэтому функция вернет то, что будет получено при обработке хвоста:
        positive_elements([_Head|Tail], TailPositive):-
          positive_elements(Tail, TailPositive).
  • #2223

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

    goal
      List = [1,-22,3,345, -3], 
      print_list(List),
      list_count_positive(List, Count),
      write("positive count: "), write(Count), nl,
      positive_elements(List, PositiveElements),
      write("positive elements: "), print_list(PositiveElements).

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