2015-04-27 67 views
2

我需要写一个谓词partition/2这样partition(L, P)成立时在列表P的列表中的每个列表的串联是一样的列表L。列表列表P可以包含任意数量的列表。在列表的列表,追加所有列表连成一个列表

实施例的查询:

? - partition ([1 ,2 ,3] , P). 
P = [[1] , [2] , [3]]; 
P = [[1] , [2 , 3]]; 
P = [[1 , 2] , [3]]; 
P = [[1 , 2 , 3]]; 
no 
? - partition (L , [[1] ,[2] ,[3 ,4 ,5]]). 
L = [1 , 2 , 3 , 4 , 5]; 
no 

我试图在P串接列表在一起,然后检查以看它是否等于L。这是我迄今为止的,但它不起作用。它无限循环地包含多于1个列表的任何P

partition([], []). ;; Partition of empty list is the empty list 
partition(L, [L]). ;; Base case where if P contains 1 element (list), L is equal to this list. 
partition(L, [X|[Y1|Y2]]) :- 
    append(X, Y1, XY1), 
    partition(L, [XY1|Y2]). ;; Append each list in P to the list after it, repeating until one list is created. X is the head of the list, Y1 is the second element, and Y2 is the rest of the list. 

任何帮助表示赞赏。

回答

3

这个棘手的部分是以通用终止的方式使用append/3

让我们的代码list_sublists/2(一个较为声明名字比partition):

list_sublists([],[]). 
list_sublists([X|Xs],[[Y|Ys]|Yss]) :- 
    append([Y|Ys],Xs0,[X|Xs]), 
    list_sublists(Xs0,Yss). 

考虑目标append([Y|Ys],Xs0,[X|Xs])第二子句中:人皆可终止时,无论是[Y|Ys][X|Xs](或两者)都在界/长度。

现在让我们来运行你给查询:

?- list_sublists([1,2,3],Pss). 
Pss = [[1],[2],[3]] ; 
Pss = [[1],[2,3]] ; 
Pss = [[1,2],[3]] ; 
Pss = [[1,2,3]]  ; 
false. 

?- list_sublists(Ls,[[1],[2],[3,4,5]]). 
Ls = [1,2,3,4,5]. 
1

我试图纠正最小代码:它结束了非常类似的(相同的,真的)到@Repeat答案(+1),当然

partition([], []). % Partition of empty list is the empty list 
%partition(L, [L]). % Base case where if P contains 1 element (list), L is equal to this list. 
% Append each list in P to the list after it, repeating until one list is created. X is the head of the list, Y1 is the second element, and Y2 is the rest of the list. 
partition(L, [[X|Xs]|Zs]) :- 
    append([X|Xs], Ys, L), 
    partition(Ys, Zs). 

我想说的伎俩它迫使附加/ 3的第一个参数有长度> 0,做到了给它的模式[X|Xs]而不是简单地Xs