【问题标题】:Reorder list in prolog序言中的重新排序列表
【发布时间】:2014-10-16 22:11:57
【问题描述】:

我想根据子列表的长度从小到大重新排列一个列表。例如,期望的答案是按子列表长度的数量重新排列,有一个长度为4,两个长度1个,3个3个长度,4个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)
    ).  

count(LIST,X)输出如下:

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

但是预期的输出是[1-3,3-1],我不知道如何处理其余的子列表(一个一个删除??)并根据模式重新排列它们[1-3, 3-1]。

有人可以帮忙吗?提前致谢。

【问题讨论】:

    标签: prolog


    【解决方案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

    【讨论】:

    • 如果你使用 List = ([[2],[3],[4],[2,3,4]], Ls)。那么预期的结果是 LS=[[2,3,4],[2],[3],[4]]。因为只有一个长度为三的子列表,长度只有一的三个子列表。这个问题与那个问题不同。仔细阅读~~
    • 这也是你得到的结果:?- lists_ascending_appearences([[2],[3],[4],[2,3,4]], Ls). 产生:Ls = [[2, 3, 4], [2], [3], [4]].
    猜你喜欢
    • 2022-10-18
    • 2019-09-18
    • 1970-01-01
    • 2023-02-21
    • 1970-01-01
    • 2015-09-16
    • 2018-06-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多