1

我知道你可以这样写一个简单的阶乘函数:

(define fact
  (lambda (n)
    (if (= n 0) 1
        (* n (fact (- n 1)))))

但是,这只有在您发送号码时才有效;如果您发送列表或符号,它将出错。所以我想做的是让它适用于所有事情,如果是列表,则对列表中的每个单独元素进行阶乘。这是我所拥有的:

(define listFact
 (lambda (n)
   (cond
     ((null? n) 1)
     ((symbol? n) n)
     ((number? n) (if (= n 0) 1 (* n (listFact (- n 1)))))
     ((cons? n) (cons (listFact(car n)) (listFact(cdr n)))))))

我不太擅长 Scheme,但我需要能够了解基础知识。除列表外,每个输入都正常工作。

> (listFact '())

1

(listFact 'a)

'一种

(清单事实 4)

24

(listFact '(1 2 3))

缺点:第二个参数必须是一个列表,但收到 6 和 1

我想要最后一个做的是返回:

(清单 1 2 6)

我不知道为什么它不起作用。如果有人能在不改变整个代码结构的情况下帮助我解决这个问题(即不使用应用/映射或多个函数),将不胜感激。我认为唯一搞砸的线路是有缺点的线路。

谢谢。

4

2 回答 2

2

只需更换

(cond
     ((null? n) 1)

(cond
     ((null? n) n)

forcons正常工作,因为尾随nil: 一个列表(1 2 3)实际上是(1 . (2 . (3 . ()))),所以你最终会到达nil列表末尾的哨兵。要重新构建列表,您需要它保持一个空列表,或者nil,以便(cons 6 nil)创建一个新列表 (6)(cons 6 1)会创建一对(6 . 1),但显然由于某种原因它在您的实现中不起作用。

如果您希望将列表中的() 元素转换为1s,则必须区分这两种情况。

于 2013-11-17T20:17:08.990 回答
0

这是你的问题:

((null? n) 1)

因此,当您尝试获取空列表的值时,您会得到一个整数,它不是列表。当你用列表调用你的函数时,你会得到类似的东西:

(cons 1 (cons 2 (cons 6 1)))

这行不通。为了修复你的功能,你应该试试这个:

((null? n) n)
于 2013-11-17T20:23:30.830 回答