将列表分成所需长度的部分

时间:2012-03-24 20:19:44

标签: prolog dcg

我试图编写谓词divide(L,Len,Slist),当Slist可以与从List L分配的长度为Len的列表统一时,这将是正确的。例如

divide([1,2,3,4,5,6,7],3,Slist).

应该给出这样的答案

Slist=[1,2,3];
Slist=[2,3,4];
Slist=[3,4,5];
Slist=[4,5,6];
Slist=[5,6,7];

但是我找不到比length(X,Len), sublist(L,X).更好的方法,但它确实工作得太慢了。 应该如何划分谓词?

2 个答案:

答案 0 :(得分:2)

或者你可以在this great answer中使用@false提到的DCG:

seq([])     --> [].
seq([E|Es]) --> [E], seq(Es).

divide(List, Length, Result) :-
    length(Result, Length),
    phrase((seq(_), seq(Result), seq(_)), List).

答案 1 :(得分:1)

子列表/ 2似乎没有按预期工作:

?- [library(dialect/sicstus/lists)].
% library(dialect/sicstus/lists) compiled into sicstus_lists 0,00 sec, 14 clauses
true.

?- L=[1,2,3,4,5,6], length(T, 3),sublist(T,L).
L = [1, 2, 3, 4, 5, 6],
T = [1, 2, 3] ;
L = [1, 2, 3, 4, 5, 6],
T = [1, 2, 4] ;
L = [1, 2, 3, 4, 5, 6],
T = [1, 2, 5] ;
....

您可以使用append / 3代替:

?- L=[1,2,3,4,5,6], length(T, 3), append(_, Q, L), append(T, _, Q).
L = [1, 2, 3, 4, 5, 6],
T = [1, 2, 3],
Q = [1, 2, 3, 4, 5, 6] ;
L = [1, 2, 3, 4, 5, 6],
T = [2, 3, 4],
Q = [2, 3, 4, 5, 6] ;
L = [1, 2, 3, 4, 5, 6],
T = [3, 4, 5],
Q = [3, 4, 5, 6] ;
L = [1, 2, 3, 4, 5, 6],
T = Q, Q = [4, 5, 6] ;
false.

我认为它不是很快,只是必不可少......