You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用cond、eql、mapcar实现树指定层级节点数统计?遇MAPCAR报错

问题分析与解决方案

错误原因

你的代码存在两个核心问题:

  1. mapcar 参数不匹配:mapcar 会为列表的每个元素传递一个参数,但你定义的 lambda 写了两个参数 (level subtree),这会导致参数绑定错误,进而触发 "proper list must not end with 1" 的异常(Lisp会尝试将多余参数当作列表处理)。
  2. 树结构处理逻辑错误:你的树结构定义为「根节点 + 子节点列表」(如 '(a (b (c)) (d) (e (f))) 中,a 是根,(b (c))、(d)、(e (f)) 是子节点),但递归时你直接将整个 tree 传给 mapcar,而非仅处理子节点部分(即 (cdr tree))。

修正后的代码

严格遵循你给定的约束(仅使用 cond、eql、mapcar),修正后的函数如下:

(defun count-nodes (level tree)
  (cond
    ((null tree) 0)
    ((eql level 0) 1)
    (t (apply #'+ (mapcar (lambda (subtree) (count-nodes (1- level) subtree))
                          (cdr tree))))))

代码解释

  • 当 tree 为空时,返回0(空树无节点)。
  • 当指定层级 level 为0时,返回1(当前节点即为目标层级的节点)。
  • 当层级大于0时,递归遍历当前节点的所有子节点((cdr tree)),对每个子节点计算 level-1 层级的节点数,最后用 apply #'+ 求和得到总数量。

测试验证

针对你补充的示例:

(write (count-nodes 1 '(a (b (c)) (d) (e (f)))))

按照你的树结构定义(根 a 为level0,子节点 b、d、e 为level1),该调用应返回3。若你期望返回1,需确认层级定义是否为「从子节点的子节点开始计数」(即level1对应 c、f 所在层级),此时调用 (count-nodes 2 '(a (b (c)) (d) (e (f)))) 会返回2。

针对你最初的错误调用,修正后执行:

(write (count-nodes 4 '(1 (2 (3 (6 7) 4) 5))))

该树的level4节点为 6 和 7,返回结果为2,运行无异常。

内容的提问来源于stack exchange,提问作者Leo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 15:35:25