2014-10-09 249 views
1

我想重新排列一個列表,根據它們從短到長的列表長度。重新排列列表元素 - 序言

的預期輸出是:

rearrange([[a,b],[c],[a,b,c],[d,d,d],[d,s],[s],[d,s,s,a]],X). 
X=[[c],[s],[a,b],[d,s],[a,b,c],[d,d,d],[d,s,s,a]]. 

我的想法是,計算每個長度第一,然後做重排。 到目前爲止,我所做的是使用模式[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

在這種情況下,keysort/2通常派上用場。例如:

lists_ascending(Lists0, Lists) :- 
    maplist(list_with_length, Lists0, LLs0), 
    keysort(LLs0, LLs), 
    pairs_values(LLs, Lists). 

list_with_length(List, L-List) :- length(List, L). 

實例查詢及其結果:

?- lists_ascending([[a,b],[c],[a,b,c],[d,d,d],[d,s],[s],[d,s,s,a]], Ls). 
Ls = [[c], [s], [a, b], [d, s], [a, b, c], [d, d, d], [d, s, s, a]] 

編輯:以下謂詞,它使用上面的代碼,各種你在下面的評論,這是概括的方式由相同長度的子列表的出現次數:

lists_ascending_appearences(Lists0, Lists) :- 
    maplist(list_with_length, Lists0, LLs0), 
    keysort(LLs0, LLs1), 
    group_pairs_by_key(LLs1, LLs2), 
    pairs_values(LLs2, Lists1), 
    lists_ascending(Lists1, Lists2), 
    append(Lists2, Lists). 

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

?- lists_ascending_appearences([[a,b],[c],[a,b,c],[d,d,d],[d,s],[s],[d,s,s,a]], Ls). 
Ls = [[d, s, s, a], [c], [s], [a, b], [d, s], [a, b, c], [d, d, d]]. 
+0

太好了。還有一個問題: – 2014-10-09 09:45:53

+0

如果我想重新排列它們像這樣: 實例查詢及其結果: – 2014-10-09 09:46:53

+0

如果我想重新排列它們像這樣: 實例查詢及其結果: lists_ascending([A,B] ,[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]]。 這是重新排列的子列表的長度數,有一個長度爲4,兩個長度爲1,三個長度爲3,四個長度爲2. 更改list_with_length(List,List-L) :-length(列表,L)。可以做到? – 2014-10-09 09:54:26