Finding the longest contiguous sublist in Prolog

后端 未结 1 1376
耶瑟儿~
耶瑟儿~ 2020-12-12 05:35

I\'m a beginner in Prolog and this is my question:

I have a sorted list of integers without duplicates i.e. [1,2,3,11,12,13,14,21,22,23,24,25]

I

相关标签:
1条回答
  • 2020-12-12 06:13

    First, we define z_nonsucc_t/3 based on clpfd and bool01_t/2:

    :- use_module(library(clpfd)).
    
    z_nonsucc_t(X,Y,T) :-
       Y #\= X+1 #<==> B,
       bool01_t(B,T).
    

    To split an integer list into consecutive runs, we use splitlistIfAdj/3 like this:

    ?- splitlistIfAdj(z_nonsucc_t,[1,2,3,11,12,13,14,21,22,23,24,25],Pss).   
    Pss = [[1,2,3],[11,12,13,14],[21,22,23,24,25]].
    

    Next, we define meta-predicate max_of_by/3 based on if_/3, (#>)/3, and (#>=)/3:

    max_of_by(X,[E|Es],P_2) :-
       call(P_2,E,V),
       max_of_by_aux(Es,P_2,V,[E],Rs),
       reverse(Rs,Xs),
       member(X,Xs).
    
    max_of_by_aux([]    , _ ,_ ,Bs ,Bs).
    max_of_by_aux([E|Es],P_2,V0,Bs0,Bs) :-
       call(P_2,E,V),
       if_(V #>  V0, Bs1=[], Bs1=Bs0),
       if_(V #>= V0, (V1 = V , Bs2 = [E|Bs1]),
                     (V1 = V0, Bs2 =    Bs1 )),
       max_of_by_aux(Es,P_2,V1,Bs2,Bs).
    

    To get the longest list(s), we use meta-predicate max_of_by/3 with length/2 like so:

    ?- max_of_by(Xs,[[1,2,3],[11,12,13,14],[21,22,23,24,25]],length).
    Xs = [21,22,23,24,25].
    

    Note that max_of_by/3 may succeed more than once in tie cases:

    ?- max_of_by(Xs,[[1,2,3],[11,12,13,14,15],[21,22,23,24,25]],length).
      Xs = [11,12,13,14,15]
    ; Xs = [21,22,23,24,25].
    

    Put it all together in predicate maxCont/2:

    maxCont(Zs,Xs) :-
       splitlistIfAdj(z_nonsucc_t,Zs,Pss),
       max_of_by(Xs,Pss,length).
    

    Sample queries:

    ?- maxCont([1,2,3,11,12,13,14,   21,22,23,24,25],Xs).
    Xs = [21,22,23,24,25].
    
    ?- maxCont([1,2,3,11,12,13,14,15,21,22,23,24,25],Xs).
      Xs = [11,12,13,14,15]
    ; Xs = [21,22,23,24,25].
    
    0 讨论(0)
提交回复
热议问题