重新排列列表元素 - Prolog

时间:2014-10-09 09:02:56

标签: prolog

我想根据子列表的长度从短到长重新排列列表。

期望输出为:

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 个答案:

答案 0 :(得分: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]].