我应该定义函数n! (N-Factorial)
。问题是我不知道该怎么做。这是我到目前为止所拥有的,有人可以帮忙吗?我不明白球拍中的条件,所以解释会很棒!
(define fact (lambda (n) (if (> n 0)) (* n < n)))
您必须首先仔细查看文档,这是一个非常简单的示例,但您必须在尝试解决方案之前了解基础知识,并确保您知道如何编写递归过程。一些评论:
(define fact
(lambda (n)
(if (> n 0)
; a conditional must have two parts:
; where is the consequent? here goes the advance of the recursion
; where is the alternative? here goes the base case of the recursion
)
(* n < n))) ; this line is outside the conditional, and it's just wrong
请注意,最后一个表达式不正确,我不知道它应该做什么,但它会引发错误。删除它,并专注于编写条件的主体。
使用方案(或 lisp)的技巧是在您将它们构建成更复杂的形式时,理解每组括号之间的每一点。
所以让我们从条件开始。 if
需要 3 个参数。它评估第一个,如果为真,则返回第二个,如果第一个参数为假,则返回第三个。
(if #t "some value" "some other value") ; => "some value"
(if #f "some value" "some other value") ; => "some other value"
(if (<= 1 0) "done" "go again") ; => "go again"
cond
也可以 - 你可以在这里阅读条件句的球拍介绍:http: //docs.racket-lang.org/guide/syntax-overview.html#%28part._.Conditionals_with_if__and__or__and_cond%29
您可以通过两种不同的方式定义函数。您正在使用匿名函数方法,这很好,但在这种情况下您不需要 lambda,因此更简单的语法是:
(define (function-name arguments) result)
例如:
(define (previous-number n)
(- n 1))
(previous-number 3) ; => 2
使用像你一样的 lambda 实现同样的事情,使用不同的语法(现在不要担心任何其他差异):
(define previous-number* (lambda (n) (- n 1)))
(previous-number* 3) ; => 2
顺便说一句 - '*' 只是该名称中的另一个字符,没什么特别的(请参阅http://docs.racket-lang.org/guide/syntax-overview.html#%28part._.Identifiers%29)。一个 '!' 在函数名的末尾通常意味着该函数有副作用,但是 n! 在这种情况下,是您的函数的好名称。
所以让我们回到你原来的问题,把函数定义和条件放在一起。我们将使用 wiki 定义中的“递归关系”,因为它提供了一个很好的递归函数:如果 n 小于 1,则阶乘为 1。否则,阶乘是 n 乘以小于 n 的阶乘。在代码中,它看起来像:
(define (n! n)
(if (<= n 1) ; If n is less than 1,
1 ; then the factorial is 1
(* n (n! (- n 1))))) ; Otherwise, the factorial is n times the factorial of one less than n.
最后一个子句比我想要的要密集一些,所以让我们把它缩小为 n = 2: (define n 2) (* n (n! (- n 1))) ; => (* 2 (n! (- 2 1))) (* 2 (n!1)) (* 2 1) 2
此外,如果您使用的是 Racket,很容易确认它是否按我们预期的那样工作:
(check-expect (n! 0) 1)
(check-expect (n! 1) 1)
(check-expect (n! 20) 2432902008176640000)