如何删除prolog中的子列表?

时间:2014-12-02 08:55:08

标签: list prolog sublist

有人可以帮帮我吗?我需要在prolog中解决这个问题而且我不知道如何......

"给出一个整数列表。删除由reduce元素组成的所有子列表。"

4 个答案:

答案 0 :(得分:3)

我们分三个步骤删除降序子列表:

  1. 分开减少和减少部分(使用 splitlistIfAdj/3(#=<)/3

    ?- splitlistIfAdj(#=<,[ 1 , 2 , 3 , 4,3,2,1 , 2 , 3 , 4,3,2,1 , 2 ],Xs1).
    Xs1 =                 [[1],[2],[3],[4,3,2,1],[2],[3],[4,3,2,1],[2]].
    
  2. 排除非单身人士名单(使用tfilter/3Prolog lambdas(=)/3

    ?- tfilter(\[_|T]^(T=[]),[[1],[2],[3],[4,3,2,1],[2],[3],[4,3,2,1],[2]],Xs2).
    Xs2 =                    [[1],[2],[3],          [2],[3],          [2]].
    
  3. 将单件列表映射到项目(使用maplist/3Prolog lambdas

    ?- maplist(\[H|_]^H^true,[[1],[2],[3],[2],[3],[2]],Xs).
    Xs =                     [ 1 , 2 , 3 , 2 , 3 , 2 ].
    
  4. 让我们把它放在一起!

    :- use_module(library(clpfd)).
    :- use_module(library(lambda)).
    
    descending_removed(Xs0,Xs) :-
       splitlistIfAdj(#=<,Xs0,Xs1),
       tfilter(\[_|T]^(T=[]),Xs1,Xs2),
       maplist(\[H|_]^H^true,Xs2,Xs).
    

    以下是一些问题:

    ?- descending_removed([1,2,3,4,3,2,1,2,3,4,3,2,1,2],Xs).
    Xs = [1,2,3,2,3,2].
    
    ?- descending_removed([4,3,2,1,0],Xs).
    Xs = [].
    
    ?- descending_removed([1,2,3,4],Xs).
    Xs = [1,2,3,4].
    
    ?- descending_removed([1,2,3,  4,3,3,2,2,1],Xs).
    Xs = [1,2,3].
    
    ?- descending_removed([1,2,3,4,4,3,3,2,2,1],Xs).
    Xs = [1,2,3,4].
    

答案 1 :(得分:3)

我们可以使用this answer代替tfilter/3maplist/3改进tchoose/3,删除两个步骤中的降序子列表 - 而不是三个:

  1. 分开减少和不减少的部分(使用splitlistIfAdj/3(#=<)/3

    ?- splitlistIfAdj(#=<,[ 1 , 2 , 3 , 4,3,2,1 , 2 , 3 , 4,3,2,1 , 2 ],Xs1).
    Xs1 =                 [[1],[2],[3],[4,3,2,1],[2],[3],[4,3,2,1],[2]].
    
  2. 过滤单件列表并映射到项目(使用tchoose/3Prolog lambdas(=)/3

    ?- tchoose(\[H|T]^H^(T=[]),[[1],[2],[3],[4,3,2,1],[2],[3],[4,3,2,1],[2]],Xs).
    Xs =                       [ 1 , 2 , 3 ,           2 , 3 ,           2 ].
    
  3. 让我们把它放在一起!

    :- use_module(library(clpfd)).
    :- use_module(library(lambda)).
    
    descending_removed(Xs0,Xs) :-
       splitlistIfAdj(#=<,Xs0,Xs1),
       tchoose(\[H|T]^H^(T=[]),Xs1,Xs).
    

    相同的查询,相同的结果:

    ?- descending_removed([1,2,3,4,3,2,1,2,3,4,3,2,1,2],Xs).
    Xs = [1,2,3,2,3,2].
    
    ?- descending_removed([4,3,2,1,0],Xs).
    Xs = [].
    
    ?- descending_removed([1,2,3,4],Xs).
    Xs = [1,2,3,4].
    
    ?- descending_removed([1,2,3,  4,3,3,2,2,1],Xs).
    Xs = [1,2,3].
    
    ?- descending_removed([1,2,3,4,4,3,3,2,2,1],Xs).
    Xs = [1,2,3,4].
    

答案 2 :(得分:2)

让我们从一些数字样本列表开始:

1 2 3 4 3 2 1 2 3 4 3 2 1 2

在删除所有递减的子列表后,我们应该

1 2 3 2 3 2

怎么可以这样做?我建议浏览列表并观察在查看数字组时如何生成“输出”:

A B C
  1 2   -> output 1
1 2 3   -> output 2
2 3 4   -> output 3
3 4 3   -> output none
4 3 2   -> output none
3 2 1   -> output none
2 1 2   -> output none
1 2 3   -> output 2
2 3 4   -> output 3
3 4 3   -> output none
4 3 2   -> output none
3 2 1   -> output none
2 1 2   -> output none
1 2     -> output 2

我们看到的是,只有当A

remove_dec([], []).
remove_dec(Input, Output) :-
    min_list(Input, Min),
    remove_dec0([ Min | Input ], Output).
remove_dec0([ A, B, C | Input], [ B | Output ]) :-
    A =< B, B =< C,
    remove_dec0([ B, C | Input], Output).
remove_dec0([ _, B, C | Input], Output) :-
    remove_dec0([ B, C | Input], Output).
remove_dec0([A, B], [B]) :-
    A =< B.
remove_dec0([A, B], []) :-
    A > B.

示例输入和输出:

?- remove_dec([1,2,3,4,3,2,1,2,3,4,3,2,1,2],R).
R = [1, 2, 3, 2, 3, 2] .

?- remove_dec([4,3,2,1,0],R).
R = [] ;
false.

?- remove_dec([1,2,3,4],R).
R = [1, 2, 3, 4] .

答案 3 :(得分:1)

(使用与之前答案相同的名称和测试):

descending_removed(L,R) :- dr(a,L,R).

dr(_,[],[]).

dr(DIR,[A|Q],R) :-
  ( [B|_]=Q, A>B ->  
        dr(d,Q,R)
  ;
        dr(a,Q,T), ( DIR=a -> R=[A|T]; R=T )
  ).

验证

test :-
  descending_removed([1,2,3,4,3,2,1,2,3,4,3,2,1,2],[1,2,3,2,3,2]),
  descending_removed([4,3,2,1,0],[]),
  descending_removed([1,2,3,4],[1,2,3,4]),
  descending_removed([1,2,3,4,3,3,2,2,1],[1,2,3]),
  descending_removed([1,2,3,4,4,3,3,2,2,1],[1,2,3,4]),
  descending_removed([1],[1]).

给出以下结果:

[debug]  ?- test.
true ;
false.

如果我们想要覆盖两个连续相等值的情况,并且解释它们不会改变曲线趋势,我们可以定义:

descending_removed(L,R) :- dr(a,L,R).

dr(_,[],[]).

dr(DIR,[A|Q],R) :-
  ( [B|_]=Q, A>B ->  
        dr(d,Q,R)
  ; [B|_]=Q, A=B ->  
        dr(DIR,Q,T), ( DIR=a -> R=[A|T]; R=T )   
  ;   
        dr(a,Q,T), ( DIR=a -> R=[A|T]; R=T )
  ).

产生以下答案:

descending_removed([1,2,2,2,3,4,3,3,2,2,1],R).
R = [1, 2, 2, 2, 3] ;
false

descending_removed([1,2,3,3,2,4,3,3,2,2,5],R).
R = [1, 2, 3, 5]
false