如果你想建立(a (b) c)
在運行時,僅使用cons
和quote
,你可以這樣寫:
(cons 'a
(cons (cons 'b nil)
(cons 'c nil)))
有5個原子(A,B,C和兩個零)樹正在興建。在實踐中,您可以使用更簡單的符號,如(list 'a (list 'b) 'c)
。
在你的函數中,你不會遞歸到你的樹的CARS中,只是CDRS。此外,當CAR不是原子時,例如當您遇到(B)
時,您將添加零(第二個cond
中的默認子句)(編輯。如kmkaplan所述,您也可以計數零,無第一個cond)。
一個簡單的方案是這樣的,基於typecase
:
(defun count-atoms (form)
(typecase form
(atom 1)
(cons (+ (count-atoms (car form))
(count-atoms (cdr form))))))
- 當遇到一個原子,則結果爲1
- 當你有一個cons單元,你總結原子數在它的車和司機。
typecase
根據其參數的類型進行調度,此處爲form
。每個子句的語法如下:(type ...body...)
,其中type
是一個類型的名稱,...body...
一個或多個表達式(隱含的progn
):如果參數匹配type
,則最後一個值是typecase
的返回值。
第一項從句(atom 1)
說:如果表格是原子,返回1。下面一個,(cons ...)
說:否則,如果表格是一個cons單元,...。這裏,atom
是一個類型的名稱,它代表不是cons
的所有內容。當然,一旦你知道某物不是原子,你就知道它必然是cons
,而第二個測試是多餘的。但是,它更具可讀性,任何體面的編譯器都會優化第二個測試。
還有一個名爲atom
的函數,它是測試值是否是原子的謂詞。這就是爲什麼,當你寫上自己的(atom 1)
,在REPL,它返回T.
又見wikipedia和賽貝爾的實用的Common Lisp的chapter about lists。
回答謝謝。 但我有一個問題。 (原子1)在這裏意味着什麼? (Atom 1)從T出來,但是它如何像第一個一樣起作用? –
@임민섭查看有關原子的編輯。 – coredump