我在编写一个从列表中选择每个元素的函数时遇到了麻烦。我要我的函数执行的操作是接收一个列表,并返回选择的元素,以及不包含该元素的新列表。该函数的调用如下所示:
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).
我很难获得想要的输出。如果有人可以告诉我我需要做什么,那将不胜感激。
谢谢。
答案 0 :(得分:1)
您的实施朝着正确的方向发展。它包含一些错误,例如,您定义了谓词pickELEMENT/2
,但随后旨在调用pick/2
。通过一些“重写”,我们获得您可能想要实现的谓词:
pick([X|XRest], X, XRest).
pick([X|XRest], Element, NewList) :-
pick(XRest, Element, NewList).
现在仍然存在语义错误:在第二个子句中,第三个参数是NewList
,因此这意味着我们“忽略”了原始列表中的X
。是的,在您的第二个子句中,您没有 pick 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).