2014-10-09 135 views
0

我想根據從小到大的子列表長度的發生來重新排列列表。例如,期望的答案由子列表的長度數重新排列,有一個長度爲4,雙長度的1,三米長度的3和四個長度2.序言中的重新排序列表

實施例的查詢,並將其結果的:

lists_ascending([[a,b],[c],[a,b,c],[d,d,d],[d,s],[s],[d,s,s,a], [s,a],[s,t],[a,b,w]],Ls). 
Ls = [[d,s,s,a],[c],[s],[a,b,c],[d,d,d],[a,b,w],[a,b],[d,s],[s,a],[s,t]] 

我的意見是計算每個長度的第一和然後執行重排。到目前爲止我所做的是使用模式[length-number]來收集長度等於第一個子列表的子列表數量。

count([],[0-0]). 
count([A|B],[L-N]):- 
    length(A,L), 
    same_length(B,L,M), 
    N is M+1. 

same_length([],_,0). 
same_length([A|B],L,N) :- 
    ( length(A,L)-> 
     same_length(B,L,M), 
     N=M+1 
    ; same_length(B,L,N) 
    ). 

計數(LIST,X)輸出如下:

21 ?- count_slot([[2],[3],[4],[2,3,4]],X). 
X = [1-3]. 

但預計產量爲[1-3,3-1],我不知道該如何處理剩下的子列表(逐個刪除??)並根據模式[1-3,3-1]重新排列它們。

有人可以幫忙嗎?先謝謝了。

回答

1

您需要考慮可能存在多個與第一個子列表長度相同的子列表。顯然,您的count/2只描述了最多隻有一個的情況,因爲它的第二個參數是長度爲1的列表。

要收集與第一個子列表長度相同的子列表,請考慮例如:

lists_same_length_as_first([Ls|Lss], Subs) :- 
    length(Ls, L), 
    phrase(length_sublists(L,Lss), Subs). 

length_sublists(_, []) --> []. 
length_sublists(L, [Sub|Subs]) --> 
    ( { length(Sub, L) } -> [Sub] 
    ; [] 
    ), 
    length_sublists(L, Subs). 

,您也可以通過使用寫include/3更緊湊:

lists_same_length_as_first([Ls|Lss], Subs) :- 
    length(Ls, L), 
    include(length_equal(L), Lss, Subs). 

length_equal(L, Ls) :- length(Ls, L). 

實施例的查詢和它的結果:

?- lists_same_length_as_first([[2],[3],[4],[2,3,4]], Ls). 
Ls = [[3], [4]]. 

順便說一下,我給了這個問題的完整解決方案here

+0

你的理解不對, – 2014-10-09 11:49:01

+0

如果你使用List =([[2],[3],[4],[2,3,4]],Ls)。然後期望的結果是LS = [[2,3,4],[2],[3],[4]]。 由於只有一個長度爲3的子列表和三個長度僅爲1的子列表,這個問題與那個不同。仔細閱讀~~ – 2014-10-09 11:49:34

+0

這也是你得到的結果:'? - lists_ascending_appearences([[2],[3],[4],[2,3,4]],Ls).'產生:'Ls = [[ 2,3,4],[2],[3],[4]] – mat 2014-10-09 12:42:03