2009-09-25 26 views
0

我需要創建這個函數flat這應該從輸入列表重新收縮新列表(但在這裏,輸入列表可以有一個嵌套列表裏面):提取列表中的每個數字並重建列表?

ex。平(A(B(C)d)A)是(ABCDA)的

我的算法是下面的,不知道這是否是正確的:

  1. 檢查列表爲空:如果沒有,去上;如果是,完成 - 返回空列表
  2. 如果列表長度爲1,完成 - 返回列表
  3. 如果列表長度超過1,我現在該做什麼? (我可以使用carcdr來提取列表,但是無論哪種情況,我怎樣才能使它遞歸地提取列表到最後,並且我在考慮使用append來重新構建列表。)

任何幫助/提示,​​將不勝感激。

+1

如果列表長度爲1它仍然看起來像'((1))',因此必須是'flat'-tened – Dirk 2009-09-25 13:04:54

+0

哦不對......忘了 – Jonathan 2009-09-25 13:11:26

回答

2

的提示是,如果列表不null?,你不應該着眼於中flat通過列表的長度,而是請檢查列表的car是否是列表本身或只是一個原子。如果它本身就是一個列表,那麼你想要將它變平,並且將列表中的cdr弄平。

編輯:好,考慮兩種不同的情況,一個在您使用cons和一個在您使用append會發生什麼:

(append '(a b c) '(d e f)) => (a b c d e f) 

(cons '(a b c) '(d e f)) => '((a b c) d e f) 

在第一種情況下,你會得到一個平坦的列表回來,在第二種情況下,你沒有得到一個平面列表。然後,您可以嘗試

(define (bad-flatten lst) 
    (if ((null? lst) 
     '() 
     (append (car (flatten lst)) (cdr (flatten lst))))) 

但如果的carlst不是列表將無法正常工作。您需要第三個案例,使用cond,如下所示:

(define (incomplete-flatten lst) 
    (cond ((null? lst) 
     '()) 
     ((list? (car lst)) 
     (append (flatten (car lst)) (flatten (cdr lst)))) 
     (else 
     ;; you need to do something different here. I can 
     ;; think of at least two options. 
     ))) 
+0

啊我怎樣才能做到這一點?壓扁名單?請多幫忙。我知道我需要把它弄平。但是如何? – Jonathan 2009-09-25 13:12:40

+0

好吧,檢查一下它的列表。我使用追加嗎?或缺點? 如果是缺點,我一次只能添加2個。因此,將汽車添加到休息中,並再次遞歸地調用該功能。 – Jonathan 2009-09-25 13:23:41

+0

謝謝我想我明白了! – Jonathan 2009-09-25 13:34:07

0

可能不是最優化的解決方案。也許你可以進一步改進:

(define (list-flatten lst) 
    (if (not (null? lst)) 
     (let loop ((args lst) (ret (list)) (c null)) 
     (if (not (null? args)) 
      (begin 
      (set! c (car args)) 
      (cond ((list? c) (loop (cdr args) (append ret (list-flatten c)) c)) 
      (else (loop (cdr args) (append ret (list c)) c)))) 
      ret)) 
     #f)) 
+0

我被提醒是多麼驚人的LISP是...我希望能夠談談LISP感覺很好,但唉,我太喜歡它了。 – 2009-09-25 16:01:27

相關問題