删除列表L的最后3个元素以在Prolog中创建列表L1

时间:2011-10-07 02:23:28

标签: list prolog

如何编写一个目标,从列表L中删除最后三个元素,生成另一个列表L1?

另外,如何编写多个目标来删除生成L2的列表L中的前三个元素和最后三个元素?

3 个答案:

答案 0 :(得分:3)

你可能想尝试这样的事情:

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).

第一个谓词将返回一个没有最后三个元素的列表,如果元素少于三个则会失败。

第二个谓词将返回没有第一个和最后三个元素的列表,并且在少于六个元素的情况下会失败。

答案 1 :(得分:3)

Prolog它与其他语言略有不同,但它也有一个值得学习的库(标准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] .

答案 2 :(得分:0)

逻辑编程的第一步,从基本情况开始。当少于三个元素时,您想要发生什么?我想你想要一个空列表?

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,不要觉得无聊,你可以简单地反转列表,删除最后三个,然后再将其翻转:

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).

(考虑一下,或许在no_first_three方面实现without_last_three更好,而不是相反)!