我正在尝试编写Tail Recursive过程来计算列表中未实例化变量的数量。我有点陷入困境,我哪里出错了。
我目前的查询如下:
count([S,L],N) :- var(S), !, N+1.
count([L],N).
答案 0 :(得分:2)
注意:此答案提供了一种递归但不是尾递归的解决方案。对于尾递归解决方案,您应该使用累加器,如此问题的其他答案中所示。
与任何递归过程一样,您应该添加适当的基本案例。 在这种情况下,它应该是一个带有空列表的子句,它返回0与未实例化变量的数量:
count([], 0).
检查你写的条款。它将两个元素的列表作为输入,而不是表示为Head项和尾列表的列表,它实际上对N没有任何作用:
count([Head|Tail], M):-
var(Head),
!,
count(Tail, N),
M is N+1.
最后,当列表的第一项不是未实例化的变量时,你还应该添加一个句子来处理这个案例:
count([_|Tail], N):- count(Tail, N).
答案 1 :(得分:2)
这是一个用于计算列表中变量的尾递归。它使用累加器技术:
count(L, N) :- count(L, 0, N). % L=list, N=count, 0=value of the sum accumulator S
count([], S, S) :- !. % the innermost call, the accumulator S (2nd arg) "copied" to final result (3rd arg)
count([H| T], S, N):- var(H), !, S1 is S+1, count(T, S1, N). % increase accumulator if H is var
count([H| T], S, N):- count(T, S, N). % keep accumulator if H is not var
所有子句中的最后一次递归调用都没有调用。
答案 2 :(得分:0)
此处没有递归,因为为了进行递归,您必须根据自身定义某些内容 - 您会注意到代码右侧缺少count/2
规则。
% two paths, variable and non-variable
% and a base case to start the count
count([S|L], N) :- var(S), !, count(L, N0), N is N0+1.
count([S|L], N) :- nonvar(S), !, count(L, N).
count([], 0).
或者,只需使用findall/3
即可完成此操作。
count_alt(L, N) :- findall(S, (member(S, L), var(S)), D), length(D, N).