2014-09-13 52 views
1

我的問題是butSecondLastAtom算法。它不起作用,因爲cdr不理解空列表。但我沒有看到其他書寫算法的方式。它在頁面的末尾。一切工作,但是當列表的最後一個元素是一個列表。 http://lpaste.net/110959如何解決cdr不理解空列表?

問題出在(cdr(cdr l))的遞歸調用中,但更多的是在第三種情況下。 Idk該做什麼。我今晚就要停下來,早上重新開始。

((and (isAtom (second_last_element l)) (notAtom (last_element l))) 
     (cons 
      (car l) 
      (butSecondLastAtom (last_element l)))) 
+0

對於不壓平,見http://stackoverflow.com/questions/25827250/deleting-second-last-atom/25828080#25828080 – uselpa 2014-09-14 07:43:45

回答

0

我想在你的代碼的主要問題是對列表的cdr使用null?cdr,無論是在flattenbutLast。不要這樣做;總是使用列表本身的過程和謂詞。

我建議如下:

壓扁列表

大多數方案有一個版本flatten內置的,這需要的嵌套列表不當名單照顧。您實現的版本是不完全正確(嘗試(flatten '())),用這一個:

(define (flatten lst) 
    (let loop ((lst lst) (res null)) 
    (cond 
     ((null? lst) res) 
     ((pair? lst) (loop (car lst) (loop (cdr lst) res))) 
     (else  (cons lst res))))) 

> (flatten '(1 2 (3 (4 5 6)))) 
'(1 2 3 4 5 6) 
> (flatten '(1 2 (3 (4 5 (6))))) 
'(1 2 3 4 5 6) 
> (flatten '()) 
'() 

跌落倒數第二個元素

所以這個現在變得更加容易,通過一個簡單的平面適當名單,而循環跟蹤最後(n-1)和倒數第二(n-2)元素。示例實現是:

(define (butSecondLastAtom lst) 
    (define flst (flatten lst)) 
    (if (< (length flst) 2) 
     flst 
     (let loop ((flst (cddr flst)) (n-2 (car flst)) (n-1 (cadr flst)) (res null)) 
     (if (null? flst) 
      (reverse (cons n-1 res)) ; here we drop the second-last element 
      (loop (cdr flst) n-1 (car flst) (cons n-2 res)))))) 

如果你想避免在列表中去兩次(用於length一次,一次循環),你也可以跟蹤長度自己:

(define (butSecondLastAtom lst) 
    (define flst (flatten lst)) 
    (let loop ((lst flst) (len 0) (n-2 #f) (n-1 #f) (res null)) 
    (if (null? lst) 
     (if (< len 2) 
      flst 
      (reverse (cons n-1 res))) ; here we drop the second-last element 
     (loop (cdr lst) (add1 len) n-1 (car lst) (if (< len 2) null (cons n-2 res)))))) 

測試

> (butSecondLastAtom '(1 2 (3 (4 5 6)))) 
'(1 2 3 4 6) 
> (butSecondLastAtom '(1 2 (3 (4 5 (6))))) 
'(1 2 3 4 6) 
> (butSecondLastAtom '(((a)))) 
'(a) 
> (butSecondLastAtom '()) 
'() 
+1

過早的優化解決方案。最後一次我計時發現,使用'length'甚至可能比不遍歷列表兩次的速度更快。 – Sylwester 2014-09-13 11:55:55

+1

@Sylwester這也是我的感覺,但我沒有測量任何東西。我也發現第一個版本更優雅。但有時不可避免有人會提出這個問題,所以在那裏;-) – uselpa 2014-09-13 15:34:40