Prolog Remove the elements between the first and t

2019-03-04 16:27发布

问题:

I am trying to keep only the first element and the last element for a list which contains only consecutive integers.

For example:

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

I can only successfully keep the last element:

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.

I have been tying to keep the first element, but it keeps giving me the last element.

If there are some elements which is not consecutive, it should do some thing like:

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

Any assistance is appreciated.

回答1:

To solve this problem you have to handle different cases, here the solution then the comment:

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

So, first of all, i've defined last/2 that simply, given a list as an input, returns the last element

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

Then with remove/3 i get the list composd by th first and the last element.

findElements/2 is used to call findElementsR/4 (to make it tail recursive). findElements/4 finds a list of consecutive elements and then calls remove/2 to get the first and the last.



标签: prolog