Prolog 打印列表中的元素,但以不同方式处理最后一个元素
我编写了一个谓词,它打印出列表中除最后一个元素之外的每个元素。最后一个要素应以不同方式处理;它应该最后打印Prolog 打印列表中的元素,但以不同方式处理最后一个元素,prolog,Prolog,我编写了一个谓词,它打印出列表中除最后一个元素之外的每个元素。最后一个要素应以不同方式处理;它应该最后打印取而代之。这就是我所拥有的 write_data([]). write_data([X]) :- !, write('LAST!'), nl. write_data([X | Rest]) :- write(x), nl, write_data(Rest). 有更好的办法吗?有没有办法在没有剪切的情况下执行此操作?您可以通过使用至少包含两个元素的列表执行统一来避免剪
代码>取而代之。这就是我所拥有的
write_data([]).
write_data([X]) :-
!, write('LAST!'), nl.
write_data([X | Rest]) :-
write(x), nl,
write_data(Rest).
有更好的办法吗?有没有办法在没有剪切的情况下执行此操作?您可以通过使用至少包含两个元素的列表执行统一来避免剪切,例如:
write_data([]).
write_data([_]) :-
write('LAST!'),
nl.
write_data([X|Rest]) :-
Rest = [_|_],
write(X), nl,
write_data(Rest).
提供对列表最后一个元素的访问的last/2
谓词的常见定义是:
last([Head| Tail], Last) :-
last(Tail, Head, Last).
last([], Last, Last).
last([Head| Tail], _, Last) :-
last(Tail, Head, Last).
当使用绑定到封闭列表的第一个参数调用时,辅助谓词last/3
,避免了假定Prolog系统实现第一个参数索引的虚假选择点。您可以修改此谓词以执行所需操作吗?删除剪切的一般经验法则是,注意包含剪切的子句中的true
,然后确保其他子句中的false
因此:
write_data([]).
write_data([X]) :-
/*!,*/write('LAST!'), nl.
write_data([X | Rest]) :-
dif(Rest,[]) , /**/
write(x), nl,
write_data(Rest).
另一种确保列表至少包含两个元素的方法:write_data([X1,X2 | Rest]):-…
@Flux:是的,但是您必须在递归中“重新打包”列表,这不是很有效。什么是“解包”?你的第一个解决方案似乎是最好的。奇怪的是,有些工作是在入口predikat中完成的,称为recursiv predikat;最好在recursiv predikat中完成所有工作。@Kintalken:a[H | T]
是一个函子,为了访问参数(H
和T
),它需要一些工作。在第一个示例中,“每次迭代”的解包次数更多(通常列表中的每个项目需要3次解包),而在后一个示例中,列表中的每个项目只有一次解包。在Prolog库中,经常会看到这种谓词,使它的解包工作更少。此外,大多数prolog解释器对第一个参数进行了一些优化,从而使其更快地匹配[]
,而不是[| |]
。当然,从概念上讲,您所说的是正确的,支持列表的树结构中存在递归下降,但是!作为一个实用的问题,编译器会做一些效率更高的事情,因此[H | T]
变得(几乎)像C结构,变量(通常)以数字作为插槽进行索引。例如
write_data([]).
write_data([X]) :-
/*!,*/write('LAST!'), nl.
write_data([X | Rest]) :-
dif(Rest,[]) , /**/
write(x), nl,
write_data(Rest).