Prolog:向右旋转列表n次

时间:2013-05-08 00:15:08

标签: prolog

处理谓词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的代码。 好像我正在递归时,尾巴没有正确地移动到头部。

1 个答案:

答案 0 :(得分:8)

您可以使用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)。您可以使用算术来解决这个问题。

为了清晰起见而修改 此谓词是为 List N 参数定义的,这些参数在调用谓词时不是变量。我无意中重新排序了原始问题中的参数,因为在Prolog中,约定是严格的输入参数应该在输出参数之前。因此, List 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中所示。它们可以如本例所示使用。