2014-11-25 76 views
1

我不明白爲什麼我的功能獲得最大數量不想工作。如果我正確地思考這個問題,如果第一個原子比第二個原子小,那麼你就調用該函數減去列表中的第一個,否則你會用列表的其餘部分構造第一個原子,最大的原子。相關代碼:在計劃列表中獲得最大數量

(define (getlargest a_list) 
    (cond 
    ((null? a_list) '()) 
    ((< (car a_list) (cadr a_list)) (getlargest (cdr a_list))) 
    (else (cons (car a_list) (getlargest(cdr a_list)))))) 

回答

4

您當前的過程在運行時失敗。即使它沒有,你是比較一個元素與下一個,但不會找到最大值,例如在這樣的列表中,它將返回1,這是不正確的:'(10 2 0 1)。還有其他的錯誤,例如 - 爲什麼你要建立一個列表作爲輸出,當答案應該是一個數字?你還必須非常小心的邊緣情況下,當列表中剩下一個元素時,你的過程失敗。

正確的方法是將假定爲最大的一個元素與所有其餘元素進行比較,如果我們發現一個元素大於假定的最大值,那麼我們找到了一個新的最大值。這就是我的意思是:

(define (getlargest a_list) 
    (if (null? a_list) ; edge case: empty list 
     #f    ; return a special value signaling error 
     (let loop ((a_list (cdr a_list)) ; rest of the list 
       (maxval (car a_list))) ; assumed maximum 
     (cond ((null? a_list) maxval) ; if the list is empty, return max 
       ((> (car a_list) maxval) ; current element > max 
       (loop (cdr a_list) (car a_list))) ; found new max 
       (else      ; otherwise 
       (loop (cdr a_list) maxval)))))) ; keep the same max 

當然,在現實生活中,我們將使用內置max程序爲同樣的目的:

(apply max a_list) 
+1

而內建的'max'很容易實現SRFI 1的'reduce':'(define(max。 (減少(lambda(ab)(如果(> ab)ab))#f項目))' – 2014-11-25 14:58:27

+0

在哪一個筆記,我想你忘了'應用'在你最後一段的某處...... – 2014-11-25 15:03:15

+1

@ ChrisJester-年輕人懂了! – 2014-11-25 15:06:09

2

有您的代碼2級的錯誤:

1)else子句中,你應該遞歸調用自己,丟棄第二個元素:

(else (getlargest (cons (car a_list) (cddr a_list)))))) 

2)你缺少只有一個元素,其中cadr將失敗

((null? (cdr a_list)) (car a_list)) 

而我個人更喜歡得到#f如果該列表是空的名單的情況。因此,該代碼將如下所示

(define (getlargest a_list) 
    (cond 
    ((null? a_list)  
    #f) 
    ((null? (cdr a_list)) 
    (car a_list)) 
    ((< (car a_list) (cadr a_list)) 
    (getlargest (cdr a_list))) 
    (else 
    (getlargest (cons (car a_list) (cddr a_list)))))) 

當然,使用foldl一個解決方案是優選的:

(define (getlargest lst) 
    (foldl (lambda (e r) (if (or (not r) (> e r)) e r)) 
     #f 
     lst)) 

,或者可能稍微更有效的:

(define (getlargest lst) 
    (if (null? lst) 
     #f 
     (foldl (lambda (e r) (if (> e r) e r)) 
      (car lst) 
      (cdr lst)))) 
+0

這兩個版本都是正確的,但我寧願使用第二個版本。第一個傳遞最大值作爲列表中的第一個元素,我寧願爲它添加一個新參數。只是我的兩美分;) – 2014-11-25 18:52:18

+0

@ÓscarLópez當然,但OP可能想知道他們的代碼中的問題。 – uselpa 2014-11-25 18:56:54

2

沒有任何環路,使用遞歸性:

(define (maximum L) 
    (if (null? (cdr L)) 
     (car L) 
     (if (< (car L) (maximum (cdr L))) 
      (maximum (cdr L)) 
      (car L) 
     ) 
    ) 
) 
0
(define (maxim lst) 
    (vector-argmax (lambda (x) x) (list->vector lst)))