我需要完成一个prolog练习,我有一半但我需要更多的东西来完成它,这就是我寻求帮助的原因。
我需要的是一个小的prolog程序,给出两个列表(L1
,L2
)和一个位置P
,将第一个列表插入第二个列表并将该列表存储在第三个列表(L3
)。
insert_at(L1,L2,P,L3)
这是一个例子:
?- insert_at ([h1,h2], [a1,a2,a3,a4], 2,L3).
L3 = [a1,h1,h2,a2,a3,a4]
我的代码就是这个:
remove_at(X,[X|Xs],1,Xs).
remove_at(X,[Y|Xs],K,[Y|Ys]) :-
K > 1,
K1 is K - 1,
remove_at(X,Xs,K1,Ys).
insert_at(X,L,K,R) :- remove_at(X,R,K,L).
我得到的是:
?- insert_at([h1,h2],[a1,a2,a3,a4],2,L3).
L3 = [a1, [h1, h2], a2, a3, a4] % What I get
L3 = [a1, h1, h2, a2, a3, a4] % What I really want
我不知道为什么我在列表中得到括号...我不想要它们,因为我解释了。 为了完成它,我还需要关注更多案例:
如果P
高于第二个列表长度,则会在L1
的末尾插入L2
。
如果我们在空列表中插入非空列表(无问题P
),我们将获得插入的列表。
如果我们在非空列表中插入一个空列表(无问题P
),我们将获得非空列表。
提前致谢
答案 0 :(得分:1)
快速解决方案:
insert_at(X, L, K, R) :-
remove_at(X, R1, K, L),
flatten(R1, R).
涉及重写remove_at
以管理列表的解决方案:
remove_at([], Y, _, Y) :- !. % added as a list base case
remove_at(_, [], _, []) :- !. % added as a list base case
remove_at([X|T], [X|Xs], 1, L) :- % handle a list [X|T] instead of just X
remove_at(T, Xs, 1, L).
remove_at(X, [Y|Xs], K, [Y|Ys]) :- % same as before :)
K > 1,
K1 is K - 1,
remove_at(X, Xs, K1, Ys).
insert_at(X, L, K, R) :- remove_at(X, R, K, L).
第二个remove_at/4
基本案例表示如果我要删除的列表为空,则结果为空并且成功。这意味着如果insert_at/4
大于K
的长度,则L
会成功,并且会返回原始列表L
作为解决方案。
如果您希望insert_at/4
在K
大于列表长度时成功,并在R
附加X
后实例化L
(相反不仅仅是L
本身),您可以将remove_at(_, [], _, []) :- !.
替换为remove_at(X, X, _, []) :- !.