2013-10-28 20 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