我需要prolog中的关系,将列表左移一个元素,以便
tmap
应该产生
shift([a,b,c,d,e,f,g,h],3,Shifted).
你可以帮助我吗?
这就是我所拥有的
Shifted = [d,e,f,g,h,a,b,c]
答案 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).