list - Lisp S 表达式和列表长度/大小

标签 list lisp common-lisp s-expression

我正在尝试仅使用 Common Lisp 函数编写一个函数,该函数将计算一个 s 表达式中有多少个 s 表达式。例如:

((x = y)(z = 1)) ;; returns 2

((x - y)) ;; returns 1

嵌套表达式是可能的:

((if x then (x = y)(z = w))) ;; returns 3

我编写了一个函数来查找长度,如果没有嵌套表达式,它就可以工作。它是:

(define (length exp)
  (cond
    ((null? exp) 0)
    (#t (+ 1 (length (cdr exp))))))

现在我对此进行了修改,尝试支持以下嵌套表达式:

(define (length exp)
  (cond
    ((null? exp) 0)
    ((list? (car exp)) (+ 1 (length (cdr exp))))
    (#t (length (cdr exp)))))   

这适用于没有嵌套的表达式,但始终比嵌套表达式的答案小 1。这是因为,以上面的示例为例,((if x then (x = y)(z = w))),首先会查看 if 并且满足第三个条件,将 cdr(表达式的其余部分作为列表)返回到 length 中。同样的情况会发生,直到到达 (x=y),此时返回 +1。这意味着表达式 (if x then .... ) 尚未计算在内。

我可以通过哪些方式来解释它?添加 +2 将过度计算未嵌套的表达式。

我需要它在一个函数中工作,因为嵌套可能发生在任何地方,所以:

((x = y) (if y then (z = w)))

最佳答案

乍一看,您的代码仅递归到右侧(cdr 端),而不递归到左侧(汽车端),因此这肯定是一个问题。

仔细一看,这甚至比那更棘手,因为你并没有完全计算缺点;您需要区分 cons 启动正确的列表与列表的 cdr 的情况。如果您要递归到汽车和 cdr,则该信息将会丢失。我们需要将 sexp 作为正确的列表进行迭代,

(defun count-proper-list (sexp)
  (cond ((atom sexp) 0)
        (t (1+ (reduce #'+ (mapcar #'count-proper-list sexp))))))

但这也会计算顶级列表,因此总是比您想要的多返回一个。所以也许,

(defun count-proper-sublist (sexp)
  (1- (count-proper-list sexp)))

关于list - Lisp S 表达式和列表长度/大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13596097/

相关文章:

lisp - 如何在普通的 lisp 中获取 64 位整数?

common-lisp - 无论如何, "probe"是普通 lisp 中的一种方法吗?

list - 在 Scala : What do I actually get? 中创建列表和集合

list - 如何编写 “set-equal?” 谓词?

css - 愚蠢的 webkit 错误 - 刷新与单击更改元素放置

lisp - 格式化列表

按 LISP 中的索引号从最大值到最小值对列表进行排序?

emacs - 加载远程 Lisp 文件

python - 有没有更好的方法在字符串列表上使用 strip() ? - Python

css - 在 ul 列表的中间 li 中对齐 div