Заменить все элементы-списки результатами их реверсирования

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

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

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

    questioner
    Участник

    Помогите решить задачу на списки:

    Реализовать функцию, которая в исходном списке заменяет все элементы-
    списки результатами их реверсирования. Реверсирование производить на
    всех уровнях вложения.
    Для списка [1, [[2, 3], 4], 5, 6] результатом будет — [1, [4, [3, 2]], 5, 6].

  • #1918

    Так как функция должна переворачивать все списки, вложенные в исходный, но порядок элементов исходного списка нужно сохранить — то для обработки элементов «главного списка» нам нужен отдельный предикат:

    nested_list_reverse([], []):-!.
    nested_list_reverse([Head|Tail], [ReverseHead|ReverseTail]):-
      recursive_reverse(Head, ReverseHead),
      nested_list_reverse(Tail, ReverseTail).

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

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

    recursive_reverse(List, ReverseList):-
      is_list(List), !, recursive_reverse(List, [], ReverseList).
    recursive_reverse(Val, Val).

    Тем не менее, проверку того, что элемент является списком целесообразнее произвести сразу – это упростит рекурсивный реверс, при этом используется встроенное правило is_list. В Turbo Prolog такого правила нет, но при необходимости можно реализовать самостоятельно:
    is_list([_]).

    recursive_reverse([], Buf, Buf):-!.
    recursive_reverse([Head|Tail], Buf, Reverse):-
      recursive_reverse(Head, HeadReverse),
      recursive_reverse(Tail, [HeadReverse|Buf], Reverse).

    1. Если исходный список пуст — то результат уже находится в буфере (присвоить третьему аргументу значение буфера);
    2. выделить из исходного списка первый элемент (Head) и остаток (Tail);
    3. рекурсивно выполнить реверс первого элемента — получить HeadReverse;
    4. добавить HeadReverse в начало буфера — получить RBuf и выполнить рекурсивный реверс Tail, вернуть полученный результат

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