Prolog删除列表中第一个和最后一个元素之间的元素

时间:2018-03-22 12:25:53

标签: prolog

我试图只保留包含连续整数的列表的第一个元素和最后一个元素。

例如:

?- remove([1,2,3,4,5], NewList).
NewList = [1,5].

我只能成功保留最后一个元素:

remove([], []).

% for consecutive integers in the list
remove([ Head | Tail ], NewList) :-
    check_consecutive(Head, Tail),
    remove(Tail, NewList).

% for the case when the list is empty
remove([ Head | Tail ], [ Head | NewList ]) :-
    not(check_consecutive(Head, Tail)),
    remove(Tail, NewList).

check_consecutive(Num, [ Head | _ ]) :-
    Num is Head - 1.

我一直想要保留第一个元素,但它一直给我最后一个元素。

如果某些元素不连续,则应该执行以下操作:

?- remove([1,2,4,5,6,8,3], NewList).
NewList = [[1,6], 8, 3]. 

感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

要解决这个问题,你必须处理不同的情况,这里的解决方案是评论:

last([E],E).
last([_|T],E):-
    last(T,E).

remove([],[]).
remove([A],[A]).
remove([A,B],[A,B]).
remove([A|B],[A,Last]):-
    last(B,Last).

findElementsR([A,B],LT,LOT,LO):-
    B =< A,
    append(LT,[A],LT1),
    remove(LT1,LRem),
    append(LOT,[LRem,[B]],LO).

findElementsR([A,B|T],LT,LOT,LO):-
    B =< A,
    append(LT,[A],LT1),
    remove(LT1,LRem),
    append(LOT,[LRem],LOT1),
    findElementsR([B|T],[],LOT1,LO).

findElementsR([A,B],LT,LOT,LO):-
    B is A+1, %consecutive
    append(LT,[A,B],LTO),
    remove(LTO,RM),
    append(LOT,[RM],LO).

findElementsR([A,B|T],LT,LOT,LO):-
    B is A+1, %consecutive
    append(LT,[A],LTO),
    findElementsR([B|T],LTO,LOT,LO).

findElements(L,LO):-
    findElementsR(L,[],[],LO).

?- findElements([3,1,2,3,2,3,4,5,2,3,4],L).
L = [[3], [1, 3], [2, 5], [2, 4]]
false

所以,首先,我已经定义了last/2,只要给出一个列表作为输入,就会返回最后一个元素

?- last([1,2,3],L).
L = 3

然后使用remove/3我得到由第一个和最后一个元素组成的列表。

findElements/2用于调用findElementsR / 4(使其尾递归)。 findElements/4找到连续元素的列表,然后调用remove/2来获取第一个和最后一个元素。