2017-07-26 67 views
1

我需要在序言中的關係轉移列表旋轉左邊一個元素,使得Prolog的移位或循環元素左

shift([a,b,c,d,e,f,g,h],3,Shifted). 

應該產生

Shifted = [d,e,f,g,h,a,b,c] 

你能幫助我嗎?

這個我有什麼

shift([], []). 
shift([H|T], L) :- 
    append(T, [H], L). 

shift(0, L, L) :- !. 
shift(N, L1, L2) :- 
    N1 is N-1, 
    shift(L1, L), 
    shift(N1, L, L2). 
+0

你有什麼試過的?你在哪裏遇到問題? – lurker

+0

* *一個*元素或* n *元素?提示:剪頭,追尾。 –

+0

我添加了我所擁有的 – user8286060

回答

5

可能有更有效的解決方案,但有關的Prolog的美麗的東西,你可以用它邏輯而不是勢在必行

這是什麼在邏輯上轉移?列表L1=Lx || LyN位置的移位給出了列表L2=Ly || Lx,使得Lx的長度恰好是N。 (注意:這裏||表示串聯)。我們如何將它翻譯成Prolog?簡單:

shift(L1, N, L2) :- 
    append(Lx, Ly, L1), % L1 is Lx || Ly 
    append(Ly, Lx, L2), % L2 is Ly || Lx 
    length(Lx, N).  % The length of Lx is N 

更新:沒有爲負N的附加要求是由註釋中的OP說。對於這種情況,需要進行上述擴展。它可以被修改,使得實際的左移位置將是總列表長度減去位置的數目:

shift(L1, N, L2) :- 
    N < 0, !,    % this is the case for negative N 
    length(L1, Len), 
    N1 is Len + N, 
    shift(L1, N1, L2). 

shift(L1, N, L2) :- 
    append(Lx, Ly, L1), % L1 is Lx || Ly 
    append(Ly, Lx, L2), % L2 is Ly || Lx 
    length(Lx, N).  % The length of Lx is N 

注意,兩種實現都對於N不超過該列表的長度僅工作。如果你想處理這種情況,你將不得不按截斷長度來截短N

更新2: 其實我已經意識到否定的情況下可以更consisely實現。這與用L2交換符號和L1相同。所以具體的情況可以用下面的代替

shift(L1, N, L2) :- 
    N < 0, !, 
    N1 is -N, 
    shift(L2, N1, L1). 
+0

你的意思是換檔不換檔? – user8286060

+0

這是一個名字。我可以編輯它,如果重要的... –

+0

當我改變班次正在與我合作,但是當我嘗試這一個。位移(A,B,C,d,E,F,G,H], - 2,移)。給我錯誤長度/ 2:域錯誤:'not_less_than_zero'預計,發現'-2' – user8286060