使用递归时如何计算一个列表(或嵌套列表的列表)中的所有原子

Hap*_*oco 0 lisp recursion common-lisp

我正在创建一个递归函数,用于计算列表中的原子数。它应该能够计算嵌套列表的原子数。例如:(a(bc)ed)或(a(bc(ge))ed),应分别计算b和c或分别计算b,c,e和d而不是整体。

这是我创建的功能:

(defun  count-atoms (mylist)
    (cond
    ((null mylist) 0)
    ((listp (car mylist)) (count-atoms (car mylist)))
    ((atom (car mylist)) (+ 1 (count-atoms (rest mylist))))
    )
)
Run Code Online (Sandbox Code Playgroud)

我得到的输出是3,但应该是5(基于(a(bc)ed))。我猜想函数到达c时就停止了。如何使函数不止于c并返回最外层列表。

Tha*_*you 5

这是我们可以对问题进行推理的一种方法-

  • 如果输入为null,则返回零

    '( )
      ^
      | 0 atoms 
    
    Run Code Online (Sandbox Code Playgroud)
  • (归纳)否则,输入至少包含一个元素。如果car是一个列表,调用count-elementscar cdr。将两个结果相加并返回。

    '( a         b c d ... )
       ^         ^
       |         | count atoms in cdr <-
       |                                \
       | count atoms in sublist   <------\_ add together
    
    Run Code Online (Sandbox Code Playgroud)
  • (归纳)否则,输入中至少有一个不是列表的元素。呼叫count-elementscdr。将一加到结果并返回。

    '( a         b c d ... )
       ^         ^
       |         | count atoms in cdr <-
       |                                \
       | one atom      <-----------------\_ add together
    
    Run Code Online (Sandbox Code Playgroud)

您看到程序的不同之处吗?