2012-11-28 38 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