简体   繁体   中英

Way of returning median value of a list? (scheme)

I'm attempting to make a procedure named median that takes the median value of a list. If the list is even, then I will return the two middle numbers. I have the logic all thought out in my head, but I'm not sure how to complete it. NOTE: I am trying to avoid using list-ref, as it would trivialize the problem. So far, my code looks like the following.

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

Now, my approach to the problem is this.

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

However, I cant seem to come up with a way that could recursively implement this pseudocode.

EDIT: Not sure if anyone is still out there willing to help, but I ended up writing an iterative procedure that will take the median index value for any odd list. My trouble now is implementing something that will make the code work for an even list, and also something that doesn't return the value in a list:

(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))

I've also came up with a seperate procedure for finding the median index when the list is even:

(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))

Seems like homework.

The straightforward solution includes list-sort ( rnrs / sorting ) unless it's already sorted, length to get the list length, list-tail to get the list from half and car for odd, and an additional cadr for the even list. You use let to do something with intermediate values.

Edit in some code even if you get it right or not. For the latter we can help you more.

(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))))))

split into two lists take the first one at a time, the second two at a time

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM