源代码:
suffix(Suffix, List) ->
Delta = length(List) - length(Suffix),
Delta >= 0 andalso nthtail(Delta, List) =:= Suffix.
如下所示重写它:
suffix(Suffix, List) ->
prefix(reverse(Suffix), reverse(List)).
如果Delta> = 0,第一个将遍历四次,第二个将遍历三次,是否正确?
答案 0 :(得分:1)
第一个(来自stdlib lists.erl)将遍历两个列表,每个两个,是的。另一方面,在第二次遍历时,所有列表单元可能都在L2缓存中,并且不必分配任何数据。您的建议也有效,但必须在堆上构建两个反向临时列表,这两个临时列表在分配和初始化数据结构以及平均更频繁地发生垃圾收集方面有成本。
如果你在C(或任何类似的语言)中考虑相同的问题:测试一个单链表是否是另一个单链表的后缀,更加明显的是为什么它很难高效,特别是如果你想要为了避免分配内存,你不能使用反转指针等技巧。
答案 1 :(得分:-1)
我不认为这是正确的。据我所知,length是一个函数内置函数,它不需要遍历列表来获得结果(这就是为什么它允许在守护测试中),而且andalso也是一种捷径。如果第一个术语是假的,它不会评估第二个术语并直接返回false。