2012-04-12 31 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)