我尝试使用递归来实现如下foo(5) = 5^4 + 4^3 + 3^2 + 2^1 + 1^0 = 701
工作方法。我一直试图遵循逻辑,但我一直在犯错误。有人可以指导我吗?
(define (foo n) ; size-n problem
( cond ( (= (- n 1) 0 ) ; stopping condition
0 ); return value
(else (+ ( expt n (- n 1) ) ( foo (- n 1) ) ) ))) ; size-m problems
答案 0 :(得分:2)
如果您正确标记了问题,则需要在Prolog中回答此问题,但您的代码片段建议您使用git log --graph --decorate --abbrev-commit
(或我不知道的语言)。
在Prolog中你写了谓词。对于您的问题,有两种情况:
lisp
小于或等于零的情况,即零:
N
foo(N,0) :-
N =< 0,
!.
大于N
时的归纳案例。在这种情况下,我们会为0
计算foo
并加起来N-1
:
N^(N-1)
您可以简单地编写包含两种情况的程序:
foo(N,S) :-
N1 is N-1,
foo(N1,T),
S is T+N^N1.
并按如下方式测试:
foo(N,0) :-
N =< 0,
!.
foo(N,S) :-
N1 is N-1,
foo(N1,T),
S is T+N^N1.
你可以通过添加对归纳案例的检查来使循环中的谓词更安全:
?- foo(-1,S).
S = 0.
?- foo(0,S).
S = 0.
?- foo(1,S).
S = 1.
?- foo(2,S).
S = 3.
?- foo(3,S).
S = 12.
?- foo(5,S).
S = 701.
或者你可以使用累加器进一步提高谓词的性能:
foo(N,0) :-
N =< 0,
!.
foo(N,S) :-
N > 0,
N1 is N-1,
foo(N1,T),
S is T+N^N1.
此版本还首先检查foo(N,S) :-
foo(N,0,S).
foo(N,S,T) :-
N > 0,
!,
N1 is N-1,
Q is S+N^N1,
foo(N1,Q,T).
foo(N,S,S) :-
N =< 0.
之前是N > 0
,因为这是一个更可能的情况:在一个N =< 0
之后我们停止递归,而N =< 0
将被调用< em> N-1 次。使用累加器启用称为尾递归的优化技术。