3

Working on a predicate, rotate(L,M,N), where L is a new list formed by rotating M to the right N times.

My approach was to just append the tail of M to its head N times.

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).

Currently, my code returns L equal to the original M, no matter what N is set to. Seems like when I'm recursing, the tail isn't properly moved to the head.

4

1 回答 1

9

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

为清楚起见编辑 此谓词是为调用谓词时不是变量的ListN参数定义的。我无意中对原始问题中的参数进行了重新排序,因为在 Prolog 中,约定是严格的输入参数应该在输出参数之前。所以,ListN和输入参数,RotatedList是一个输出参数。所以这些是正确的查询:

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

但是这个:

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

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

阅读 SWI-Prolog 文档时,请注意标有“?”的谓词参数,如length. 它们可以如本例所示那样使用。

于 2013-05-08T01:50:56.017 回答