2013-10-28 19 views
0

我正在試圖製作一個名爲median的程序,它取得一個列表的中間值。如果列表是偶數,那麼我將返回兩個中間數字。我的頭腦中有所有想到的邏輯,但我不知道如何完成它。注:我試圖避免使用list-ref,因爲它會使問題微不足道。 到目前爲止,我的代碼如下所示。返回列表中值的方法? (方案)

(define (median lst) 
(if (null? lst) 
    '() 
    (if (even? lst) ; ends here 

現在,我對這個問題的方法是這樣的。

Odd #- Return the value of the "car#" that's in place of (/ (+ (length lst) 1) 2) 
3; 2nd car  (1 100 3) => 100 
5; 3rd car  (1 2 100 4 5) => 100 
7; 4th car  (1 2 3 100 5 6 7) => 100 
Even # - Return the value of the "car#" that's in place of (/ (length lst) 2) AND (+ (/ (length lst) 2) 1) 
2; 1st and 2nd car   (1 2) => 1 2 
4; 2nd and 3rd car   (1 20 30 4) => 20 30 

不過,我似乎無法拿出,可以遞歸實現這個僞代碼的方式。

編輯:不確定是否有人仍然在那裏願意幫助,但我最終編寫了一個迭代過程,將採取任何奇數列表的中值索引值。我現在的麻煩是實施東西,這將使該代碼工作的,甚至列表,也未嘗沒有在列表返回值:

(define (median-index-odd lst) 
    (define (median-index-iter1 lst times_carred) 
     (if (null? lst) 
      '() 
      (if (= times_carred (/ (+ (length lst) 1) 2)) 
       (list (car lst))    
       (median-index-iter1 (cdr lst) (+ 1 times_carred))))) 
       (median-index-iter1 lst 0)) 

我也想出了一個單獨的程序找到當名單是偶數時的中值指數:

(define (median-index-even lst) 
    (define (median-index-iter2 lst times_carred) 
     (if (null? lst) 
      '() 
      (if (= times_carred (/ (length lst) 2)) 
       (list (car lst) (cadr lst))    
       (median-index-iter2 (cdr lst) (+ 1 times_carred))))) 
       (median-index-iter2 lst 0)) 
+1

的[獲得從列表中方案的中間元件]可能的複製(http://stackoverflow.com/問題/ 13306626 /獲取中間人元素 - 從列表式的方案)。 –

回答

0

似乎像功課。

直截了當的解決方案包括list-sortrnrs/sorting),除非它已經排序,length以獲取列表長度,list-tail擺脫一半的名單和car爲奇,和偶數列表附加cadr。您使用let來處理中間值。

在某些代碼中進行編輯,即使您得到正確與否。對於後者,我們可以幫助你更多。

+1

不,有一種方法不使用「長度」。 :-)查看我發佈的dupe鏈接,它包含我爲類似問題編寫的答案。 –

+0

@ ChrisJester-Young確實,但不那麼簡單。它們之間的差異很小。例如。 ikarus中有1億個元素。 t&h使用0.80s,而長度+列表尾使用1.10s。即簡單的解決方案對於大多數列表來說表現相當不錯,使用T&H重寫它很有趣,但過早優化。 – Sylwester

0
(define (median L) 
(if (null? L) 
    (error "No median of empty list") 
    (let loop ((L1 L) (L2 L)) 
     (cond ((null? (cdr L2)) (car L1)) 
      ((null? (cddr L2)) (list (car L1) (cadr L1))) 
      (else (loop (cdr L1) (cddr L2)))))) 

分裂成兩個列表取第一次一個,第二每次兩個

+0

基本上和[我的回答](http://stackoverflow.com/a/13308315/13)一樣,除了在單中位數情況下我還是小心地返回一個列表,這樣如果元素沒有信息丟失本身是列表(並且還允許我在給出空列表時返回空列表,而不是拋出錯誤)。 :-) –

+0

你的是有點不同,因爲它檢查週期,但邏輯是相同的。老實說,我讀過這個問題,就像「哦,我知道這個」,讀了西爾韋斯特的回答,然後發佈了我的問題。錯過了小小的評論。 – WorBlux