未初始化變量我試圖寫一個尾遞歸方法來計算列表中的未初始化變量的數目。我有點卡住了,我哪裏錯了。Prolog的尾遞歸方法來計算列表
我當前的查詢是以下:
count([S,L],N) :- var(S), !, N+1.
count([L],N).
未初始化變量我試圖寫一個尾遞歸方法來計算列表中的未初始化變量的數目。我有點卡住了,我哪裏錯了。Prolog的尾遞歸方法來計算列表
我當前的查詢是以下:
count([S,L],N) :- var(S), !, N+1.
count([L],N).
注:這個答案提出了一個解決方案,它是遞歸的,但不是尾遞歸。對於尾遞歸解決方案,您應該使用累加器,這可以從此問題的其他答案中看出。
與任何遞歸過程,你應該添加適當的基本情況。 在這種情況下,它應該是與返回與未初始化變量的數目統一0空單的條款:
count([], 0).
檢查你寫的條款。它輸入兩個元素,而不是表現爲頭項和尾單的列表清單,它確實沒有什麼用N:
count([Head|Tail], M):-
var(Head),
!,
count(Tail, N),
M is N+1.
最後,你還應該添加一個條款來處理該情況下,當列表的第一個項目是不是一個非實例變量:
count([_|Tail], N):- count(Tail, N).
沒有遞歸在這裏,因爲爲了有遞歸,你必須在本身來定義的東西 - 你會發現代碼右側缺少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).
這是一個用於計數列表中變量的尾遞歸。它使用累加器技術:
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
沒有調用在所有子句中都跟隨最後的遞歸調用。
這不是一個尾遞歸因爲遞歸調用'計數(尾,N)'之後是進一步的目標'M是N + 1'。 – Jiri
@Jini:你是對的!我監督了問題的「尾遞歸」部分,我只是修正了OP代碼。 – gusbro