Prolog移位或旋转元素

时间:2017-07-26 20:39:30

标签: prolog

我需要prolog中的关系,将列表左移一个元素,以便

tmap

应该产生

shift([a,b,c,d,e,f,g,h],3,Shifted).
你可以帮助我吗?

这就是我所拥有的

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

1 个答案:

答案 0 :(得分:6)

可能有更有效的解决方案,但Prolog的美妙之处在于,您可以使用逻辑而不是强制性地

这在逻辑上有什么变化?将列表L1=Lx || Ly移至N个位置会使列表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

更新: OP在评论中说明了负N的额外要求。对于这种情况,需要扩展上述内容。可以对其进行修改,使得实际的左移位置将是总列表长度减去位置的数量:

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: 我实际上已经意识到负面情况可以更加明确地实施。它与交换符号和L1与L2相同。因此具体案例可以用以下内容替换

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