2014-11-05 44 views
1

我正在从SICP(而不是家庭作业)练习,练习2.20引入了点尾符号,这是您使用(define (f a . b) ...)来传递可变数量参数(最终列表为b)的地方。此问题特别需要一个采用整数a的过程,并返回所有参数的列表,其中奇偶校验的值等于a's。问题并不难,这里是我的解决方案:如何在此算法中正确使用虚线符号?

(define (same-parity a . b); a is an int, b is any number of int arguments 
    (let ((parity (remainder a 2))) 
    (define (proc li) 
     (cond ((null? li) null) 
      ; If parity of the head of the list is = parity of a, 
      ((= (remainder (car li) 2) parity) 
      ; keep it and check the rest of the list. 
      (cons (car li) (proc (cdr li)))) 
      ; Otherwise ignore it and check the rest of the list. 
      (else (proc (cdr li))))) 
    (cons a (proc b)))) 

我的问题是,我似乎并没有使用虚线拖尾功能。我可能刚刚接受了两个参数,一个数字和一个列表;我正在有效地将算法包装在proc的程序中,该程序消除了虚线的事情。

之前,我写了这个解决方案,我想有一个递归调用类似

(same-parity a . (cdr b))

什么精神上的相似,但无论我怎么试了一下,我不停地传递列表或额外的程序或列表随你。这可能是因为我不知道究竟是.做什么,只是我想要做的事情(Racket文档没有清除任何内容)。总结起来,

是我的解决方案是什么打算用于这个练习,或者有没有一种方法来实际使用算法中的点符号(这似乎是练习的重点)?

回答

2

您不能使用(same-parity a . (cdr b))(因为这会被读入为(same-parity a cdr b)),但您可以使用(apply same-parity a (cdr b))。这就是你如何将一个列表“插入”参数。

但是,您所使用的“内部程序”方法通常效率更高,因为进行的列表复制更少。