簡體   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