从列表中选取元素 Prolog



我在编写一个函数时遇到了一些麻烦,该函数将从列表中挑选每个元素。我希望我的函数做的是接收一个列表,并返回选取的元素,以及一个没有元素的新列表。对该函数的调用如下所示:

pickElement([LIST], PICKEDELEMENT, NEWLIST).

因此,如果我传入列表 [1,2,3],我希望函数传递三次,输出如下所示:

PICKEDELEMENT = 1
NEWLIST = [2,3]
PICKEDELEMENT = 2
NEWLIST = [1,3]
PICKEDELEMENT = 3
NEWLIST = [1,3]

我编写了以下函数,但是在它选择一个元素后,它会将其从我不想要的列表中删除。

pickELEMENT([X|XREST],X,XREST).
pickELEMENT([X|XREST],PICKEDELEMENT,NEWLIST) :- 
pick(XREST,PICKEDELEMENT,NEWLIST).

我很难获得我正在寻找的输出。如果有人能告诉我我需要做什么,将不胜感激。

谢谢。

你的实现方向很好。它包含一些错误,例如您定义了一个谓词pickELEMENT/2,但随后旨在调用pick/2。通过一些"重写",我们得到了你想要实现的谓词:

pick([X|XRest], X, XRest).
pick([X|XRest], Element,NewList) :- 
pick(XRest, Element, NewList).

现在仍然存在一个语义错误:在您的第二个子句中,第三个参数是NewList,所以这意味着我们"忽略"原始列表中的X。是的,在你的第二个子句中,你没有选择X,但这意味着它应该是NewList的一部分,所以我们在递归调用的结果前面加上X,比如:

pick([X|XRest], X, XRest).
pick([X|XRest], Element,[X|NewList]) :- 
pick(XRest, Element, NewList).

以上可以改进,这里我们将解压缩两次"cons"列表元素:一次在第一条中,一次在第二句中。我们可以通过实现pick/4谓词来防止这种低效率,并将pick/3重定向到如下所示pick/4

pick([H|T], X, NewList) :-
pick(T, H, X, NewList).
pick(XRest, X, X, XRest).
pick([X2|XRest], X, Element, [X|NewList]) :- 
pick(XRest, X2, Element, NewList).

最新更新