【发布时间】:2021-06-15 05:28:59
【问题描述】:
我处于以下情况:我有一个列表,我只想从中删除最后一个元素。
我已经实施了以下规则(效果不佳):
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 是真的,这意味着这是最后一个元素,所以我从原始列表中删除它
但这在我看来不是很清楚,也不是很好,我想知道是否有针对此问题的声明性好的解决方案。
【问题讨论】: