2012-04-12 55 views
3

我需要从列表中只有那些奇数值,所以我试图打破使用汽车和CDR功能,我的名单返回。我有一个递归函数调用,用于检查Car是否返回一个列表,然后使用car和cdr进一步分解它,否则将第一个元素传递给函数调用检查是否为Odd。如何打破(11(12 13)),使用汽车和CDR方案

与特殊情况(10 11(12 13))的问题是, 车返回10点 CDR返回(11(12 13))

然后在第二次迭代 车返回(图11(12 13 )) CDR回报率(11(12 13))

那么,如何进一步打破使用car和cdr我的名单。我需要在最终答案中保留括号,并且只返回具有奇数整数值的列表。

+1

我很困惑,'(11(12 13))'的'car'是'11'。它看起来像你的程序中有某种逻辑错误,因为在高层次上,你描述的方法听起来像是可行的,只要你在遇到列表的时候小心地递归,比如用'((12 13 ))'。 – 2012-04-12 13:45:49

回答

4

的需要任意嵌套列表我发现很容易先写扁平列表版本(在我们的例子过滤奇),然后编辑它来产生嵌套的版本上运行的功能(我将其称为过滤余*)

首先进行正常过滤奇

(define filter-odd 
    (lambda (ls) 
     (cond 
     [(null? ls) '()] 
     [(odd? (car ls)) (cons (car ls) (filter-odd (cdr ls)))] 
     [else (filter-odd (cdr ls))]))) 

现在对于过滤奇*(一个右侧将留作练习(尽管它好像你知道从你的答案问题))

(define filter-odd* 
    (lambda (ls) 
     (cond 
     [(null? ls) '()] 
     [(list? (car ls)) #| Do something with both car and cdr of ls |# ] 
     [(odd? (car ls)) (cons (car ls) (filter-odd* (cdr ls)))] 
     [else (filter-odd* (cdr ls))]))) 

需要注意的是,这种设计模式可以用来帮助编写任何递归程序,并将其从仅在平面列表中工作转换为在任意深度列表上工作。

1

这里有一个通用的解决方案,用于列表与嵌套的任意级别:

(define (odds-list lst) 
    (cond ((null? lst) '())     ; the list is empty 
     ((not (list? (car lst)))   ; first element is not a list 
     (if (odd? (car lst))    ; element is odd 
      (cons (car lst) (odds-list (cdr lst))) ; build the returned list 
      (odds-list (cdr lst))))  ; element is even 
     (else (cons (odds-list (car lst)) ; first element is a list 
        (odds-list (cdr lst)))))) 

注意到有三个情况下需要考虑:

  1. 如果列表为空
  2. 如果列表中的第一个元素是不是列表
  3. 如果列表中的第一个元素是一个列表

对于第二种情况,另外两个情况需要考虑:

  1. 如果元素是奇数,那么我们把它添加到返回
  2. 如果元素是偶数,我们跳过它,继续列表下一个元素
+0

非常感谢!它解决了我的问题。高兴的帮助:)! – Basmah 2012-04-17 18:14:34

0

这是我的看法:

(define filter* 
    (lambda (e f) 
    (cond ((pair? e) 
      (append (filter* (car e) f) 
        (filter* (cdr e) f))) 
      ((null? e) '()) 
      ((f e) (list e)) 
      (else '())))) 

,然后你可以这样做:

> (filter* '(1 (2 . 3) ((4 . 5))) even?) 
(2 4) 
> (filter* '(1 (2 . 3) ((4 . 5))) odd?) 
(1 3 5)