2013-05-08 36 views
3

使用謂詞,rotate(L,M,N),其中L是通過將M旋轉到右邊N次所形成的新列表。序言:正確旋轉列表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

提示:只需兩次調用'append',您就可以更高效地完成此操作。 – 2013-05-08 00:30:20

+0

@larsmans你的意思是隻有兩個電話追加?我需要不斷減少N嗎? – 2013-05-08 00:47:10

回答

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)。你可以用算術來解決這個問題。

爲清楚起見

編輯該斷言爲列表ñ論據是不變量時,謂詞被稱爲定義。我無意中重新排序了原始問題的參數,因爲在Prolog中,約定是嚴格地輸入參數應該在輸出參數之前出現。因此,列表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。它們可以按照此示例中所示的方式使用。

+0

我沒有看到如何爲'N>長度(L)'做這項工作。似乎它需要某種遞歸調用來旋轉,同時改變/跟蹤N的值。但是,這似乎過於複雜的事情。 – 2013-05-08 21:56:31

+0

@AdamDuvall模塊化算術 – 2013-05-08 23:11:40

+0

因此,目前它超時如果'N>長度(L)',是有一種方式來使用國防部的想法,以便它停在某一點,不超時的想法? – 2013-05-08 23:46:39