2012-11-28 61 views
1

我正在嘗試使用Common Lisp函數編寫一個函數,只會計算s表達式中有多少個s表達式。例如:Lisp 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))) 
+1

這看起來很奇怪。你說'我正在嘗試使用Common Lisp函數編寫函數'。然而,你的代碼在Scheme中? –

+0

@RainerJoswig我的代碼在方案中,但我只使用LISP數字基元,謂詞和函數。 – darksky

+0

好吧,但這與Common Lisp無關。 Common Lisp有很多功能 - 不僅僅是一個教育計劃。 –

回答

2

乍一看,你的代碼只遞歸向右(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))) 
+0

謝謝。我不確定mapcar或reduce是做什麼的,但我不允許爲此使用它們。我看到我的問題在哪裏。這就是我錯過了遞歸中的一些列表或元素。從概念上講,我需要將sexp作爲適當的列表。 1-如何完成? 2-我將如何檢測嵌套的兩性手術?對不起,我沒有把它全部。 – darksky