【问题标题】:Find all lists of sublists that when concatenated give a given list查找连接时给出给定列表的所有子列表列表
【发布时间】:2020-01-14 18:29:35
【问题描述】:

我写了这个函数,它的第一个参数是列表列表,它在第二个参数中生成连接所有列表的结果。

appall([],[]).
appall([H|T],V) :- appall(T,V1), append(H,V1,V).

但是,我希望它反过来工作 - appall(X,[1,2,3]) - 给我X = [[],[1,2,3]] 然后X=[[1],[2,3]] 等等。这不起作用,因为调用 appall(T, V1) 没有减少。

我该如何解决?

【问题讨论】:

    标签: prolog


    【解决方案1】:

    这是一种解决方案:

    split([],[]).
    split([Head|Tail],[[Head]|Split]) :-
        split(Tail,Split).
    split([Head|Tail],[[Head|List]|Split]) :-
        split(Tail,[List|Split]).
    

    例如:

    ?- split([1,2,3,4],Lists), split(Recover,Lists).
    Lists = [[1], [2], [3], [4]],
    Recover = [1, 2, 3, 4] ;
    Lists = [[1], [2], [3, 4]],
    Recover = [1, 2, 3, 4] ;
    Lists = [[1], [2, 3], [4]],
    Recover = [1, 2, 3, 4] ;
    Lists = [[1], [2, 3, 4]],
    Recover = [1, 2, 3, 4] ;
    Lists = [[1, 2], [3], [4]],
    Recover = [1, 2, 3, 4] ;
    Lists = [[1, 2], [3, 4]],
    Recover = [1, 2, 3, 4] ;
    Lists = [[1, 2, 3], [4]],
    Recover = [1, 2, 3, 4] ;
    Lists = [[1, 2, 3, 4]],
    Recover = [1, 2, 3, 4] ;
    false.
    

    此解决方案基于以下观察。我将扁平化列表称为输入列表,将未扁平化列表称为输出列表。在递归情况下,输入列表具有[H|T] 的形式,split(T,R) 假设成功。需要考虑三种情况。

    1. 如果R = [],我们可以开始构造一个新列表,其最后一个元素是H
    2. 如果R = [_|_],我们可以开始构造一个新列表,其最后一个元素是H
    3. 如果R = [L|_],我们可以通过将H 附加到L 来继续构造L

    在每种情况下,我们都会获得有效的输出列表。前两种情况由split/2的第二个子句实现(R = []R = [_|_]无所谓),第三个由第三个子句实现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-10
      相关资源
      最近更新 更多