LISP-从列表中添加所有原子(任意级别)
我猜这应该是用LISP很容易做到的事情(他们这样叫是有原因的),但我不能把我的想法放在它上面 假设我有以下列表: ((1 2 3)(4(5 6))) 我想把它们全部加起来,结果应该是21 我开始很简单,尝试从一个很好的列表中添加元素(如(1、2、3)),我几乎做到了:LISP-从列表中添加所有原子(任意级别),lisp,add,Lisp,Add,我猜这应该是用LISP很容易做到的事情(他们这样叫是有原因的),但我不能把我的想法放在它上面 假设我有以下列表: ((1 2 3)(4(5 6))) 我想把它们全部加起来,结果应该是21 我开始很简单,尝试从一个很好的列表中添加元素(如(1、2、3)),我几乎做到了: (defun sum (list) (if list (+ (car list) (sum (cdr list))) 0) ) 也许有更好的编码方式和更好的排列方式,但现在这种(几乎类似C的)缩进
(defun sum (list)
(if list
(+ (car list) (sum (cdr list)))
0)
)
也许有更好的编码方式和更好的排列方式,但现在这种(几乎类似C的)缩进样式帮助我跟踪括号。它是有效的
不幸的是,对于我示例中的列表来说,这还不够好。所以我又试了一次:
(defun sum (list)
(cond
( (atom (car list)) (+ (car list) (sum (cdr list))) )
( (list (car list)) (+ (sum (car list) ) (sum (cdr list))))
)
)
这看起来不仅仅是过度杀戮,它是过度杀戮,因为即使对于简单的示例,我也会遇到堆栈溢出错误
编辑:
我成功地编写了一个工作(但不那么复杂)的函数:
(defun sum (l)
(cond
((null l) 0)
((atom (car l)) (+ (car l) (sum (cdr l))))
((+ (sum (car l)) (sum (cdr l))))
)
)
你很接近。调整您的第一个变体:
(defun sum (list)
(if list
(+ (sum (car list)) (sum (cdr list)))
0)
)
因为(汽车列表)
本身可能是一个列表,而不一定是一个数字
因此,现在我们必须使这项工作起作用,以防它是一个数字-不仅是car
,而且是cdr
:
(defun sum (list)
(if (not (listp list))
; an obvious result here...
...
; or else it's a list
(+ (sum (car list)) (sum (cdr list)))
0)
)
但是等等,这里确实有三种情况——非空列表、空列表和非列表。相应地修改代码。你很接近了。调整您的第一个变体:
(defun sum (list)
(if list
(+ (sum (car list)) (sum (cdr list)))
0)
)
因为(汽车列表)
本身可能是一个列表,而不一定是一个数字
因此,现在我们必须使这项工作起作用,以防它是一个数字-不仅是car
,而且是cdr
:
(defun sum (list)
(if (not (listp list))
; an obvious result here...
...
; or else it's a list
(+ (sum (car list)) (sum (cdr list)))
0)
)
但是等等,这里确实有三种情况——非空列表、空列表和非列表。相应地修改代码。您说过:
也许有更好的编码方式和更好的排列方式,但现在这种(几乎类似C的)缩进样式帮助我跟踪括号。它是有效的
任何现代编辑都会帮你的。编辑器缩进并计算括号数。压痕是否正确非常重要
设置Lisp代码格式的最佳方法如下:
(defun sum (list)
(if list
(+ (car list)
(sum (cdr list)))
0))
(defun sum (list)
(cond ((null list) 0) ; termination test first
((atom (first list)) (+ (first list) ; FIRST not CAR
(sum (rest list)))) ; REST not CDR
(t (+ (sum (first list))
(sum (rest list))))))
编写函数的更好方法如下:
(defun sum (list)
(if list
(+ (car list)
(sum (cdr list)))
0))
(defun sum (list)
(cond ((null list) 0) ; termination test first
((atom (first list)) (+ (first list) ; FIRST not CAR
(sum (rest list)))) ; REST not CDR
(t (+ (sum (first list))
(sum (rest list))))))
稍有不同的版本:
(defun sum (list)
(if (null list) ; termination test first
0 ; termination value
(destructuring-bind (head . tail) ; bind variables
list ; matching with LIST
(+ (if (atom head) ; all list elements are numbers
head
(sum head))
(sum tail)))))
你说:
也许有更好的编码方式和更好的排列方式,但现在这种(几乎类似C的)缩进样式帮助我跟踪括号。它是有效的
任何现代编辑都会帮你的。编辑器缩进并计算括号数。压痕是否正确非常重要
设置Lisp代码格式的最佳方法如下:
(defun sum (list)
(if list
(+ (car list)
(sum (cdr list)))
0))
(defun sum (list)
(cond ((null list) 0) ; termination test first
((atom (first list)) (+ (first list) ; FIRST not CAR
(sum (rest list)))) ; REST not CDR
(t (+ (sum (first list))
(sum (rest list))))))
编写函数的更好方法如下:
(defun sum (list)
(if list
(+ (car list)
(sum (cdr list)))
0))
(defun sum (list)
(cond ((null list) 0) ; termination test first
((atom (first list)) (+ (first list) ; FIRST not CAR
(sum (rest list)))) ; REST not CDR
(t (+ (sum (first list))
(sum (rest list))))))
稍有不同的版本:
(defun sum (list)
(if (null list) ; termination test first
0 ; termination value
(destructuring-bind (head . tail) ; bind variables
list ; matching with LIST
(+ (if (atom head) ; all list elements are numbers
head
(sum head))
(sum tail)))))
谢谢我尝试应用你的建议编辑了我的代码,结果非常接近。谢谢。我试图应用你的建议编辑了我的代码,结果非常接近。可能的重复是如何减少树元素上的加法函数的问题。我链接到的副本询问如何减少树上的函数,并使用加法作为一个具体示例。@Joshua Taylor close,但我对在不展平列表的情况下进行此操作感兴趣(我在尝试做其他事情时,很容易做到展平)。有趣的链接和示例:)@user3002428扁平化只是随着
append
和[]
而减少,因为求和随着+
和0
而减少。这可能重复的问题是如何减少树元素上的加法函数。我链接到的副本询问如何减少树上的函数,并使用加法作为一个具体示例。@Joshua Taylor close,但我对在不展平列表的情况下进行此操作感兴趣(我在尝试做其他事情时,很容易做到展平)。有趣的链接和示例:)@user3002428扁平化只是随着append
和[]
而减少,因为求和随着+
和0
而减少。重新更正缩进,我注意到Emacs对if
表单的else分支使用了“body indentation”,但在Scheme世界中,将else分支缩进与then分支齐平更为常见(Riastradh的样式指南支持这一点)。渴望听到你对这一切的想法。@ChrisJester-Young:“同花顺”版本很常见;-)在公共Lisp中,也是。我使用LispWorks,它的编辑器使用这种样式——尽管可以进行不同的配置。此样式也用于Emacs Lisp。在Lisp机器上,您可以在不同的缩进变量之间循环。重新更正缩进,我注意到Emacs对if
表单的else分支使用“body indentation”,但在Scheme世界中,将else分支缩进与then分支齐平(Riastrah的样式指南支持这一点)。渴望听到你对这一切的想法。@ChrisJester-Young:“同花顺”版本很常见;-)在公共Lisp中,也是。我使用LispWorks,它的编辑器使用这种样式——尽管可以进行不同的配置。此样式也用于Emacs Lisp。在Lisp机器上,您可以在不同的缩进变体之间循环。