我知道你可以这样写一个简单的阶乘函数:
(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)
“一
(listFact 4)
24
(listFact'(1 2 3))
缺点:第二个参数必须是一个列表,但是收到了6和1
我想要的最后一件事是返回:
(清单1 2 6)
我不知道为什么它不起作用。如果有人可以帮助我在不改变代码的整个结构的情况下解决这个问题(即不使用apply / map或多个函数),那将非常感激。我认为唯一搞砸的是有缺点的那条线。
感谢。
答案 0 :(得分:1)
只需替换
(cond
((null? n) 1)
与
(cond
((null? n) n)
让cons
正常工作,因为结尾nil
:列表(1 2 3)
实际上是(1 . (2 . (3 . ())))
,因此您最终会转到哨兵nil
在列表的最后。要重新构建列表,您需要将其保留为空列表或nil
,以便(cons 6 nil)
创建新的列表 (6)
; (cons 6 1)
会创建一对(6 . 1)
但显然由于某种原因它在您的实现中不起作用。
如果您希望列表中的()
元素转换为1
,则必须区分这两种情况。
答案 1 :(得分:0)
这是你的问题:
((null? n) 1)
因此,当您尝试获取空列表的值时,您将获得一个整数,该整数不是列表。当您使用列表调用函数时,您会得到类似的结果:
(cons 1 (cons 2 (cons 6 1)))
这不起作用。为了修复你的功能,你应该试试这个:
((null? n) n)