我需要prolog中的关系来将列表左移一个元素,这样就可以了
shift([a,b,c,d,e,f,g,h],3,Shifted).
Run Code Online (Sandbox Code Playgroud)
应该产生
Shifted = [d,e,f,g,h,a,b,c]
Run Code Online (Sandbox Code Playgroud)
你可以帮帮我吗?
这就是我所拥有的
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).
Run Code Online (Sandbox Code Playgroud)
可能有更有效的解决方案,但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
Run Code Online (Sandbox Code Playgroud)
更新: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
Run Code Online (Sandbox Code Playgroud)
请注意,这两种实现仅适用于不超过列表长度的N. 如果要处理它的情况,则必须N按模数截断列表的长度.
更新2: 我实际上已经意识到负面情况可以更加明确地实施.它与交换符号和L1与L2相同.因此具体案例可以用以下内容代替
shift(L1, N, L2) :-
N < 0, !,
N1 is -N,
shift(L2, N1, L1).
Run Code Online (Sandbox Code Playgroud)