我处于以下情况:我有一个列表,我只想从中删除最后一个元素。
我已经实施了以下规则(效果不佳):
deleteLastElement([Only],WithoutLast) :-
!,
delete([Only],Only,WithoutLast).
deleteLastElement([_|Tail],WithoutLast) :-
!,
deleteLastElement(Tail,WithoutLast).
问题是当我调用它时,列表中的所有元素都被删除了,实际上如果我执行以下语句我得到:
[debug] ?- deleteLastElement([a,b,c], List).
List = [].
查看跟踪我认为这很清楚导致此问题的原因:
[trace] ?- deleteLastElement([a,b], List).
Call: (7) deleteLastElement([a, b], _G396) ? creep
Call: (8) deleteLastElement([b], _G396) ? creep
Call: (9) lists:delete([b], b, _G396) ? creep
Exit: (9) lists:delete([b], b, []) ? creep
Exit: (8) deleteLastElement([b], []) ? creep
Exit: (7) deleteLastElement([a, b], []) ? creep
List = [].
当达到基本情况时,WithoutLast列表与空列表[] 统一,并且在执行回溯时,WithoutLast仍然是空列表。
情况不妙。
我正在考虑执行以下操作来实现它:
- 在调用删除最后一个元素的谓词之前计算列表中元素的数量。
- 递归迭代,每次递减元素个数的值
- 如果元素的数量为 0,则表示这是最后一个元素,因此我将其从原始列表中删除
但这在我看来并不清楚而且不太好,我会知道是否有针对此问题的声明性良好解决方案。