2014-12-02 99 views
4

有人可以幫我嗎?我需要在序言中解決這個問題,我不知道如何...如何刪除prolog中的子列表?

「給定一個整數列表,刪除所有由減少元素組成的子列表。

+2

你能展示一些嘗試嗎?請閱讀[Stackoverflow Tour](http://stackoverflow.com/tour)瞭解如何提出正確的問題。 – lurker 2014-12-02 12:04:03

回答

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 

我們看到的是從中間的B柱,我們輸出的數量僅僅當A <乙< C.所以這就是我們可以做的事情:我們可以查看整個列表並檢查數字三元組。如果the're進行排序,然後我們輸出B.

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] . 
+0

@repeat,您引用的條款不存在。你是否打算用'一次(A> B; B> C)'重新解答'A = 2015-08-13 11:32:26

+1

我的意思是'remove_dec0([_,B,C | Input],Output):remove_dec0([B,C | Input],Output)。'最好是:'remove_dec0([A,B, C | Input],Output): - 一次(A> B; B> C),remove_dec0([B,C | Input],Output).'所以這個子句和上面的那個變成互斥的(不使用剪切在那一級)。 – repeat 2015-08-13 11:49:36

+1

@Grzegorz:在A = 2015-08-16 08:34:13

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 ]. 
    

讓我們放它在一起!

:- 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]. 
3

我們可以通過使用tchoose/3代替tfilter/3maplist/3,在步驟去除降子列表---不是三個提高this answer

  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 ]. 
    

讓我們把它在一起!

:- 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]. 
+0

它提供了哪些結果來查詢「descending_removed([1,2,3,3,2,4,3,3,2,2,5],R)」。 ? (對不起,我自己沒有測試lambda包)。 – 2015-08-16 10:47:58

+0

@pasabaporaqui:您使用哪種Prolog系統?您應該能夠將模塊複製粘貼到任何符合要求的系統中。 – false 2015-08-17 17:58:20

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