LISP中如何传递列表参数?阶乘列表生成实现求助
正确实现生成0到n的阶乘列表的方法
错误原因分析
- 第一个错误:
(mapcar 'factor3 '(my-seq 5 NIL))中,'(my-seq 5 NIL)是字面符号列表,不是执行my-seq函数的结果。mapcar会把列表里的my-seq、5、NIL这三个符号逐个传给factor3,而factor3需要的是数字,自然触发类型错误。 - 第二个错误:
(mapcar 'factor3 'b)里的'b是引用符号b本身,不是取变量b存储的列表值。mapcar要求第二个参数是合法列表,符号显然不满足,因此报错。
正确调用方式
要让mapcar处理my-seq返回的整数列表,必须直接执行my-seq函数(不要加引号),或者正确引用变量的值:
方式1:直接在mapcar中调用my-seq
; 生成1-5的阶乘列表 (mapcar 'factor3 (my-seq 5 NIL)) ; 要包含0的阶乘,手动把0加入列表 (mapcar 'factor3 (cons 0 (my-seq 5 NIL)))
方式2:先存变量再调用
(setq num-list (cons 0 (my-seq 5 NIL))) (mapcar 'factor3 num-list) ; 注意这里不要加引号引用num-list
优化现有函数
- 修复factor3的0值处理:当前
factor3传入0时,loop会生成空列表,apply #'*空列表会报错,修改为:
(defun factor3 (N) (if (zerop N) 1 ; 0的阶乘定义为1 (apply #'* (loop :for n :from 1 :to N :collect n))))
- 简化my-seq函数:去掉冗余的累加器参数,直接用loop生成列表:
(defun my-seq (num) (loop :for n :from 1 :to num :collect n))
调用时只需(my-seq 5)即可得到(1 2 3 4 5),更简洁。
最终完整实现
如果要直接写一个生成0到n阶乘列表的函数,可以合并逻辑:
(defun factor3 (N) (if (zerop N) 1 (apply #'* (loop :for n :from 1 :to N :collect n)))) (defun factorial-list (n) (mapcar 'factor3 (loop :for i :from 0 :to n :collect i))) ; 调用示例 (factorial-list 5) ; 返回 (1 1 2 6 24 120)
内容的提问来源于stack exchange,提问作者user3261716
相关产品推荐
相关产品推荐

