序言:旋转列表n次权(Prolog: Rotate list n times right)

2019-09-02 05:12发布

在谓词工作, rotate(L,M,N)其中, L是通过旋转形成一个新的列表M向右N倍。

我的方法是尾部只是追加M到它的头N倍。

rotate(L, M, N) :- 
   (  N > 0,
      rotate2(L, M, N)
   ;  L = M
   ).

rotate2(L, [H|T], Ct) :- 
   append(T, [H], L), 
   Ct2 is Ct - 1, 
   rotate2(L, T, Ct2).

目前,我的代码返回L等于原来的M ,不管是什么N设置为。 好像当我递归,尾部没有正确地移动到头部。

Answer 1:

您可以使用append分裂列表和length来创建列表:

% rotate(+List, +N, -RotatedList)
% True when RotatedList is List rotated N positions to the right
rotate(List, N, RotatedList) :-
    length(Back, N),           % create a list of variables of length N
    append(Front, Back, List), % split L
    append(Back, Front, RotatedList).

注意:这仅适用于N <=长度(L)。 你可以用算术来解决这个问题。

为了清楚起见,该断言为列表N个参数不属于变量时,谓词被称为定义编辑 。 我无意间重新排序的争论从你原来的问题,因为在序言中,惯例是严格的输入参数应该输出参数之前。 因此, 列表N和输入参数,RotatedList是一个输出参数。 因此,这些都是正确的查询:

?- rotate([a,b,c], 2, R).
?- rotate([a,b,c], 1, [c,a,b]).

但是这个:

?- rotate(L, 2, [a,b,c]).

将进入无限递归找到一个答案了。

当读SWI-Prolog的文档,寻找出标有“?”谓词的参数,如length 。 它们可以被用来作为本示例所示。



文章来源: Prolog: Rotate list n times right
标签: prolog