2010-11-05 26 views
4

我有一個基本的clisp函數,我只是返回列表中的原子數。我遇到的問題是我需要它爲列表中的列表中的原子增加,而不是將列表看作列表中的1個元素。區分列表和普通lisp中的原子

我猜想的真正問題是如何在代碼中區分元素是列表還是原子?如果我能做到這一點,我可以將這些列表發送到另一個函數來合併並返回它們包含的原子數。

清澈如泥? :)

我這裏有一個例子:

(defun list_length (a) 
    (cond ((null a) 0) 
     (t (+ 1 (list_length (cdr a)))))) 

如果在父表中沒有列出嵌入,例如, '(1 2 3 (4 5) 6)將返回5.我需要它包括4個和5這個偉大的工程而不是列表(4 5)。

感謝您的幫助。

喬恩


編輯:

(defun list_length (a) 
    (cond ((null a) 0) 
     ((listp (car a)) (list_length (car a))) 
     (t (+ 1 (list_length (cdr a)))))) 

[18]> (list_length '(1 2 3 (4 5) 6)) 
1. Trace: (LIST_LENGTH '(1 2 3 (4 5) 6)) 
2. Trace: (LIST_LENGTH '(2 3 (4 5) 6)) 
3. Trace: (LIST_LENGTH '(3 (4 5) 6)) 
4. Trace: (LIST_LENGTH '((4 5) 6)) 
5. Trace: (LIST_LENGTH '(4 5)) 
6. Trace: (LIST_LENGTH '(5)) 
7. Trace: (LIST_LENGTH 'NIL) 
7. Trace: LIST_LENGTH ==> 0 
6. Trace: LIST_LENGTH ==> 1 
5. Trace: LIST_LENGTH ==> 2 
4. Trace: LIST_LENGTH ==> 2 
3. Trace: LIST_LENGTH ==> 3 
2. Trace: LIST_LENGTH ==> 4 
1. Trace: LIST_LENGTH ==> 5 
5 
[19]> (dribble) 
+0

真棒,這正是我正在尋找。謝謝sepp2k。但是,這導致我到另一個問題......這是我的新代碼... (defun定義list_length(一) \t(條件((空一)0) \t \t((listp(車))( list_length(car a))) \t \t(t(+ 1(list_length(cdr a))))) ) 再次使用我的例子。它實際上會看到(4 5)是一個列表,然後進入它並計算這兩個原子,但是當它返回時,它忘記了大約6,然後返回程序。所以它增加了1 2 3 4 5,而不是6.我會在下面粘貼一個跟蹤。 – jmd4931 2010-11-05 01:14:07

+0

這是醜陋的,張貼在上面的代碼。我發佈之前,我看到你的答覆的其餘部分,雖然我會嘗試添加該行的最後一部分。 – jmd4931 2010-11-05 01:18:27

回答

4

(listp foo)將返回t如果foo是列表,nil否則。

所以,你可以讓你的list_length功能通過將以下情況下您cond處理嵌套列表:

((listp (car a)) (+ (list_length (car a)) (list_length (cdr a)))) 
+0

好東西謝謝! – jmd4931 2010-11-05 01:40:23

3

ATOM是你所要求的謂語。

我推薦使用FLATTEN,這是一個標準例程,用於將list列入列表中 - 我在此提供一個實現。

(defun flatten (x) 
    "descend into the supplied list until an atom is hit. 
append the atom to the flattened rest" 
    (if (endp x) 
     x 
    (if (atom (car x)) 
    (append (list (car x)) (flatten (cdr x))) 
     (append (flatten (car x)) (flatten (cdr x)))))) 

Flatten返回一個列表:您可以在列表上運行LENGTH來查看您結束了多少個ATOMS。

+0

這是一個很好的建議,但我可能無法避免改變原始列表。:( – jmd4931 2010-11-05 01:41:31

+0

你並沒有改變原來的,你正在返回一個新的列表 – 2010-11-05 02:02:18

+0

你是對的:)這也適用,它絕對是與我原來的方法不同的思考方式。謝謝您的幫助! – jmd4931 2010-11-05 02:31:56