2017-07-26 64 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