在给定位置P. Prolog的情况下将列表插入另一个列表

时间:2013-12-29 21:37:55

标签: list prolog

我需要完成一个prolog练习,我有一半但我需要更多的东西来完成它,这就是我寻求帮助的原因。 我需要的是一个小的prolog程序,给出两个列表(L1L2)和一个位置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),我们将获得非空列表。

提前致谢

1 个答案:

答案 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/4K大于列表长度时成功,并在R附加X后实例化L(相反不仅仅是L本身),您可以将remove_at(_, [], _, []) :- !.替换为remove_at(X, X, _, []) :- !.