我试图执行嵌套列表尾递归而不使用使用内置的flatten
func
我的例子是列表中所有值的总和
sum(LIST,SUM):-sum(LIST,0,SUM).
sum([],SUM,SUM).
sum([A|LIST],RES,SUM):-sum(A,RES2,SUM), RES1 is RES+RES2,sum(LIST,RES1,SUM).
sum([H|LIST],RES,SUM):-RES1 is RES+H,sum(LIST,RES1,SUM).
例如在展平列表
上[trace] 13 ?- sum([1,2,3,4,5,6],Sum).
Sum = 21.
但如果我尝试嵌套列表
[trace] 12 ?- sum([1,2,[3,4],5,6],Sum).
这不是工作
感谢您的帮助
答案 0 :(得分:0)
您可以在预处理步骤中使用flatten
。将您的sum
重命名为sum_flatten
,然后添加
sum(List, Sum) :-
flatten(List, FlattenList),
sum_flatten(FlattenList, Sum).
答案 1 :(得分:0)
如果没有教授如何解决这些问题的基础知识,你就会得到这种作业真的很奇怪。为什么需要重新实现库谓词呢?
您可以查看library predicate flatten/2
的实施情况。请注意,它已被弃用。这是因为,我引用,"结束需要flatten/3
经常表示,如append/3
附加两个列表,一个糟糕的设计"。
即使您不使用flatten/2
,它也会向您展示如何处理嵌套列表(这可能表明设计不合理,但无论如何)。
sum_nested([], Sum, Sum) :- !.
sum_nested([X|Xs], Acc, Sum) :- !,
sum_nested(X, 0, Sum_Nested),
Acc1 is Acc + Sum_Nested,
sum_nested(Xs, Acc1, Sum).
sum_nested(Number, Acc, Sum) :-
Sum is Number + Acc.
如果您希望谓词成功一次,则无法保留剪辑。您还应该注意到它不是严格的尾递归。你可以让它尾递归吗?什么样的输入会导致谓词失败?如果嵌套列表中有变量,会发生什么?
答案 2 :(得分:0)
避免展平的可能方法/ 2是制作(某种)成员/ 2,如
leafs([E|L], R) :- !, (leafs(E, R) ; leafs(L, R)).
leafs(E, E) :- E \= [].
现在库(聚合)可以像
一样服务sum(LIST, SUM) :- aggregate(sum(E), leafs(LIST, E), SUM).
给
?- sum([1,[[2],3]],X).
X = 6.