繁体   English   中英

对 Prolog 中的递归计数器感到困惑

[英]Confused about recursive counters in Prolog

几天来我一直被这个问题困扰。 所以给定一个形式为 t(Tree, Value, Tree) 的平衡树,我想找到左边树的深度,我用下面的代码做了:

depthLeft(nil, 1).
depthLeft(t(Tree1, _, _), N) :-
    depthLeft(Tree1, N1),
    N is N1 + 1.

所以代码有效,但我在柜台很困惑。 首先,为什么不能将计数器放在递归调用之上? 其次,为什么你不能争辩说 N1 是 N - 1 而不是像这里那样返回列表的第 n 个元素:

element_at(X,[X|_],1).
element_at(X,[_|L],K) :- K > 1, K1 is K - 1, element_at(X,L,K1).

我不明白为什么计数器在这里有不同的逻辑。 如果有人能指出我的方向,将不胜感激。

首先,为什么不能将计数器放在递归调用之上?

因为这样做是行不通的; Prolog 不是魔法,它以一种在真实计算机上运行的方式运行,这种方式对于 1970 年代的计算机来说足够简单 - 从顶部逐行:

depthLeft(t(Tree1, _, _), N) :-    % this holds if
    N is N1 + 1.                   % (calculate N1 + 1, error, N1 has no value).
    depthLeft(Tree1, N1),          % stopped before getting here.

其次,为什么你不能争辩说 N1 是 N - 1 而不是像这里那样返回列表的第 n 个元素:

反之,您提供K作为所需元素的索引,以便在到达该代码后立即计算K-1 如果你想输入“我的树的深度是 4 吗?” 然后你可以重新排列,这样N1就可以有一个值,但这与“我的树的深度是多少?”是不同的问题。

您可以从零开始计数,随着您下降到树中而增加,在末尾停止,以尾递归方式(没有剩余工作),然后返回最终计数。 或者你一无所知地下降到树中,等待稍后的加法工作,直到你到达末尾,在那里计数 1,然后通过调用堆栈上升回来做所有未决的加法,直到你回到你的答案开始。 这种方式往往写起来更简单但是吃的更多 memory 性能更差。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM