Удалить элементы списка между заданными

      Комментарии к записи Удалить элементы списка между заданными отключены

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

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

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

    questioner
    Участник

    Задан числовой список. Удалить элементы, стоящие на позициях между заданными M и N. Помогите решить на SWI-Prolog.

  • #1780

    Можно использовать для этого стандартные предикаты append и length.

    slice_list(Source, N, M, Slice):-
      append(Left, SliceWithRight, Source),
      append(Slice, _Right, SliceWithRight),
      SliceLen is M - N,
      length(Left, N), length(Slice, SliceLen), !.

    Сначала исходный список делится на 2 части — левую (Left) и правую (SliceWithRight, содержащую нужные нам элементы и «мусор»).
    SliceWithRight делится еще раз на левую (Slice, результат) и правую части. все это можно выполнить при помощи стандартного предиката append, который разделит исходный список всеми возможными способами и остается лишь указать ему длины списков.
    Очевидно, длина самого левого списка равна N, а длина среза вычисляется как M-N. Задать длины можно стандартным предикатом length.

    • #1781

      questioner
      Участник

      Все правильно, и нормально исполнено, но как выполнить реверс результата? Потому что, данная программа выводит список от N к M, а не удаляет его.

      • #1782

        В SWI Prolog встроено правило reverse, которое переворачивает список.
        Про удаление я не прочитал. Реверс удалению не поможет, для удаления части списка вам достаточно соединить самую левую и самую правую части:

        slice_remove(Source, N, M, LeftAndRight):-
          append(Left, SliceWithRight, Source),
          append(Slice, Right, SliceWithRight),
          SliceLen is M - N,
          length(Left, N), length(Slice, SliceLen), 
          append(Left, Right, LeftAndRight), !.

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