计划因素(事实* l)问题

时间:2009-09-05 22:27:11

标签: scheme

我是Scheme的新手,请原谅我的问题:我有一个计算数字列表的阶乘的函数,但它给出了结果中最后一个数字之前的一段时间。我哪里错了?

的代码:

#lang scheme

 (define fact
    (lambda (n)
      (cond
        ((= n 0) 1)
        ((= n 1) 1)
        (else (* n (fact (- n 1)))))))

 (define fact*
   (lambda (l)
     (cond
       ((null? (cdr l)) (fact (car l)))
       (else
        (cons (fact (car l)) (fact* (cdr l)))))))

输出:

> (fact* '(3 6 7 2 4 5))
(6 720 5040 2 24 . 120)

3 个答案:

答案 0 :(得分:8)

您所做的是创建improper list。试试这个:

(define fact*
   (lambda (l)
     (cond
       ((null? (cdr l)) (list (fact (car l))))
       (else
        (cons (fact (car l)) (fact* (cdr l)))))))

在第四行中添加list可以使其按预期工作。更好的可能是以下内容:

(define fact*
   (lambda (l)
     (cond
       (null? l) '())
       (else
        (cons (fact (car l)) (fact* (cdr l)))))))

这样,您的fact*功能就可以处理空列表,并减少拨打fact的地方数量。

答案 1 :(得分:5)

other answers指出了您fact*函数导致错误列表的原因。我只想指出您可以使用higher-order function map

(define fact*
  (lambda (l)
    (map fact l))

(fact* '(3 6 7 2 4 5))

map将一个函数和一个列表作为参数,并将该函数应用于列表中的每个元素,从而生成一个新列表。

答案 2 :(得分:1)

使用append代替conscons用于构造对,这就是为什么你有“。”。用于分隔一对元素。这是一个例子:

(define (factorial n)
  (if (<= n 1)
      1
      (* n (factorial (- n 1)))))

(define (factorial-list l)
  (if (null? l)
      '()
      (append (list (factorial (car l))) 
              (factorial-list (cdr l)))))