Удалите последние 3 элемента списка L, чтобы сделать список L1 в прологе - PullRequest
1 голос
/ 07 октября 2011

Как мне написать цель, которая удаляет последние три элемента из списка L, создавая другой список L1?

Кроме того, как бы я написал несколько целей, чтобы удалить первые три элемента и последние три элемента из списка L, создающего L2?

Ответы [ 3 ]

3 голосов
/ 07 октября 2011

Возможно, вы захотите попробовать что-то вроде этого:

without_last_three([_,_,_], []).
without_last_three([Head|Tail], [Head|NTail]):-
  without_last_three(Tail, NTail).

without_three_sides([_,_,_|L], L2):-
  without_last_three(L, L2).

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

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

3 голосов
/ 08 октября 2011

Пролог немного отличается от других языков, но в нем также есть библиотека (стандарт ISO), которую стоит изучить:

delete_last_3(L, L1) :-  
 append(L1, [_,_,_], L).

Теперь другой запрос выполняется легко:

delete_first_and_last_3(L, L2) :-  
  append([_,_,_], LT, L), delete_last_3(LT, L2).

Тест:

?- delete_last_3([1,2,3,4,5,6,7],X).
X = [1, 2, 3, 4] .

?- delete_first_and_last_3([1,2,3,4,5,6,7,8,9],L).
L = [4, 5, 6] .
0 голосов
/ 07 октября 2011

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

without_last_three([], []).
without_last_three([_], []).
without_last_three([_,_], []).
without_last_three([_,_,_], []).

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

without_last_three([A|L], [A|M]) :- without_last_three(L, M). !!wrong

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

without_last_three([A,B,C,D|L], [A|M]) :- without_last_three([B,C,D|L], M).

Но более элегантным решением было бы использование оператора обрезки Prolog:

without_last_three([A|L], [A|M]) :- !, without_last_three(L, M).

Для реализациибез_первого_три, не скучая, вы можете просто перевернуть список, удалить последние три и снова перевернуть его:

without_first_three(I, O) :- reverse(I, A), without_last_three(A, B), reverse(B, O).

или просто написать несколько действительно простых правил:

without_first_three([], []).
without_first_three([_], []).
without_first_three([_,_], []).
without_first_three([_,_,_|L], L).

(Подумав об этом, может быть, было бы лучше реализовать без_last_three в терминах без_первого_трека, а не наоборот)!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...