我想将prolog列表中的元素移动到同一列表中的新位置,类似于cut&粘贴操作。
例如,如果我有列表[1,2,3,4,5]
我想要类似的东西:
move(List, D1, D2, D3, Newlist)
List =原始列表,D1 =从哪个元素,D2 =到列表的哪个元素,列表中的D3目的地。
一个例子:
move([1,2,3,4,5,6,7,8,9], 1, 3, 5, NewList) :- (Implementation).
NewList = [4,5,1,2,3,6,7,8,9].
我在D3> D2,以及类似于D2< D2的情况。 D3,但我认为我没有。
% Move D3 > D2 & D2
move([X|L], D1, D2, D3, Resultado) :-
movevalue([X|L], D1, D2, Z),
moveinsert([X|L], Z, D3, ParteB),
primerapartel([X|L], D3, PrimeraParte),
deleting(PrimeraParte, D1, D2, ParteA),
append(ParteA, ParteB, Resultado),
!.
movevalue([X|L], D1, D2, Z) :-
D1 > 1,
E1 is D1 - 1,
E2 is D2 - 1,
movevalue(L, E1, E2, Z),
!.
movevalue([X|L], 1, D2, [X|Z]) :-
D2 > 0,
E2 is D2 - 1,
movevalue(L, 1, E2, Z).
movevalue([X|L], 1, 0, Z) :-
Z = [].
moveinsert([X|L], Z, D3, Resultado) :-
D3 > 1,
E3 is D3 - 1,
moveinsert(L, Z, E3, Resultado),
!.
moveinsert([X|L], Z, 1, Resultado) :-
append(Z,L,Resultado).
%append([X],Z,Resultado2)
%Primera parte L
primerapartel(_, 0, Resultado) :-
Resultado = [], !.
primerapartel([X|L], N, [X|Resultado]) :-
N > 0,
N1 is N - 1,
primerapartel(L, N1, Resultado),
!.
deleting(Lista, D1, D2, Resultado) :-
deletingizq(Lista, D1, D2, ResultadoA),
deletingder(Lista, D1, D2, ResultadoB),
append(ResultadoA, ResultadoB, Resultado),
!.
deletingizq([Princi|Pal], D1, D2, [Princi|Resultado]) :-
D1 > 1,
E1 is D1 - 1,
E2 is D2 - 1,
deletingizq(Pal, E1, E2, Resultado).
deletingizq([X|L], 1, D2, Resultado) :-
D2 > 1,
E2 is D2-1,
deletingizq(L, 1, E2, Resultado).
deletingizq([X|L], 1, 1, Resultado) :-
Resultado = [].
deletingder([Princi|Pal], D1, D2, Resultado) :-
D1 > 1,
E1 is D1 - 1,
E2 is D2 - 1,
deletingder(Pal, E1, E2, Resultado).
deletingder([X|L], 1, D2, Resultado) :-
D2 > 1,
E2 is D2 - 1,
deletingder(L, 1, E2, Resultado).
deletingder([X|L], 1, 1, Resultado) :-
Resultado = L.
答案 0 :(得分:2)
你发现Prolog列表难以通过索引处理。
为了使问题更具说明性,因此可以在Prolog中解决,我会在length / 2和nth1 / 3的帮助下将索引与映射分开。
首先,我们知道Result的长度与List相同。强制执行:
move(List, Start, Stop, Target, Result) :-
length(List, N),
length(Result, N),
move_elements(1, N, List, Start, Stop, Target, Result).
移动元素需要将索引从List映射到Result,我们必须为每个元素执行:
/* edit: see the code below - this is buggy
move_elements(I, N, _List, _Start, _Stop, _Target, _Result) :-
I =:= N + 1.
move_elements(I, N, List, Start, Stop, Target, Result) :-
nth1(I, List, E),
index_map(I, Start, Stop, Target, P),
nth1(P, Result, E),
J is I + 1,
move_elements(J, N, List, Start, Stop, Target, Result).
*/
move_elements(I, N, List, Start, Stop, Target, Result) :-
I =< N,
nth1(I, List, E),
index_map(I, Start, Stop, Target, P),
nth1(P, Result, E),
J is I + 1,
!, move_elements(J, N, List, Start, Stop, Target, Result).
move_elements(_I, _N, _List, _Start, _Stop, _Target, _Result).
我们留下了困难的部分:index_map 必须做一些算术,在可用的位置之间玩杂耍。我认为到目前为止问题有点不明确。以下是基本案例,涵盖了您的测试查询:
index_map(I, Start, Stop, Target, P) :-
I >= Start,
I =< Stop,
P is Target - (Stop - Start + 1) + I.
index_map(_I, _Start, _Stop, _Target, _P).
您应该添加更多测试以指定更多约束,但请注意index_map / 5 的最后一个子句允许 Prolog搜索匹配的元素(通过{{1} }),从而以简单的方式完成映射。
编辑:在foreach / 2的帮助下,我们可以避免循环
nth1(P, Result, E)