Prolog:删除所有连续的整数子列表

时间:2015-11-18 17:42:21

标签: list prolog sublist

所以我遇到了这个Prolog问题:

  

给定一个线性数字列表,删除连续值的所有序列。

     

E.g。 remove([1, 2, 4, 6, 7, 8, 10], L)将生成L=[4, 10]

我设法编写了这段代码:

consecutive(N,P):-
    N is P-1.

removeS([],[]).
removeS([H],[H]).

removeS([H1,H2],[]):-
    consecutive(H1,H2).
removeS([H1,H2|T],[H1|L]):-
    not(consecutive(H1,H2)),
    removeS([H2|T],L).
removeS([H1,H2,H3|T],L):-
    consecutive(H1,H2),
    not(consecutive(H2,H3)),
    removeS([H3|T],L).
removeS([H1,H2,H3|T],L):-
    consecutive(H1,H2),
    consecutive(H2,H3),
    removeS([H3|T],L).

它几乎适用于某些情况:

removeS([1,2,3,4,5,2,3,4,5,6,7,9,11],R). -->  R = [5, 9, 11];
Here only 9 and 11 should be displayed

removeS([3,2,1,2,3,4,5,2,3,4,5,6,7,9,11],R). --> R = [3, 2, 5, 9, 11];
Here only 3,2,9,11 should appear in R

在计算下一步时,需要考虑增加序列的最后一个数字。

我在这里做错了什么?

2 个答案:

答案 0 :(得分:1)

在这个答案中,我们将Prolog lambdas与两个结合使用。

:- use_module(library(lambda)).

基于append/2split_if_adj/3tfilter/3(=)/3z_nonsucc_t/3我们定义:

consecutives_removed(Xss, Zs) :-
   split_if_adj(z_nonsucc_t, Xss, Yss),
   tfilter(\[_|Xs]^(Xs=[]), Yss, Zss),
   append(Zss, Zs).

示例查询(由OP给出):

?- consecutives_removed([1,2,4,6,7,8,10], Xs).
Xs = [4,10].

?- consecutives_removed([1,2,3,4,5,2,3,4,5,6,7,9,11], Xs).
Xs = [9,11].

?- consecutives_removed([3,2,1,2,3,4,5,2,3,4,5,6,7,9,11], Xs).
Xs = [3,2,9,11].

答案 1 :(得分:0)

你做的不那么普遍(结果,更复杂),而不是需要。

?- removeS([1,2,3],R).
R = [3] ;
false.

我已经引入了一个服务谓词,“吃掉”所有连续的,并简化了逻辑,当两个连续出现时,启动它,我有:

?- removeS([3,2,1,2,3,4,5,2,3,4,5,6,7,9,11],L).
L = [3, 2, 9, 11].

修改

这是我的定义。切割可以删除,否则你可以做的替代,但恕我直言,这只会整个混乱。或者,简单地说,丢弃它并用一次/ 1包裹removeS / 2顶部调用。

removeS([],[]).
removeS([A,B|T],L):- succ(A,B), eat(A,[B|T],R), !, removeS(R, L).
removeS([A|B],[A|L]) :- removeS(B,L).

eat(A,[B|T],R) :- succ(A,B), eat(B,T,R).
eat(_,T,T).