方案 - 从已排序列表中的中位数列表中获取中位数
Scheme - Get median from a list of median from already sorted list
我试图创建的程序是一个可以执行从平均值到 std-dev 等一系列数学函数的程序,但我被绊倒的是中值。该列表已经排序,所以我怎样才能得到这个列表的长度来确定是偶数还是奇数,然后从中得到中位数。当前代码如下。 Scheme 很新,所以语法对我来说仍然很混乱。
代码
(define make-tswb
(lambda ()
(let ((records '()))
(lambda (command . args)
(cond
((equal? command 'empty?)
(null? records))
((equal? command 'add!)
(set! records (cons (car args) records)))
((equal? command 'get)
(letrec ((sort-records (lambda (r) (sort r (lambda (x y) (<= (car x) (car y)))))))
(if (null? args)
(sort-records records)
(sort-records (filter(car args) records)))))
((equal? command 'analytic)
(cond
((= (length args) 1)
((car args) records))
((= (length args) 2)
((car args) (filter (cadr args) records))))))))))
(define listofVal
(lambda (lst)
(if (null? lst)
'()
(sort (map cadddr lst) <))))
(define median
(lambda (medianList)
(let ((values (listofVal medianList)))
(let ((len (length medianList)))
// ??????????
(define tswb (make-tswb))
(tswb 'add! '(2 123 "temp1" 76.1))
(tswb 'add! '(1 123 "temp1" 72.0))
(tswb 'add! '(1 123 "temp1" 75.0))
(tswb 'analytic median)
根据this page,你需要处理两种情况:
- 列表的长度为偶数。
- 不是偶数
第一种情况,需要取中间的两个值,求和再除以二。对于第二种情况,你需要找到排序列表的中间值,这个值将是中位数。
所以,我认为这对你有用:
(define (count-median-for-even len listOfVal)
(/ (+ (list-ref listOfVal (round (- (/ len 2) 1)))
(list-ref listOfVal (round (/ len 2)))) 2))
(define (count-median-for-odd len listOfVal)
(list-ref listOfVal (round (/ len 2))))
(define median
(lambda (medianList)
(let ((values (listofVal medianList)))
(let ((len (length medianList)))
(if (even? len) (count-median-for-even len values) (count-median-for-odd len values))))))
在上面 link 的三个测试用例上测试了这个,我可以说这一定能满足你的需求。
我试图创建的程序是一个可以执行从平均值到 std-dev 等一系列数学函数的程序,但我被绊倒的是中值。该列表已经排序,所以我怎样才能得到这个列表的长度来确定是偶数还是奇数,然后从中得到中位数。当前代码如下。 Scheme 很新,所以语法对我来说仍然很混乱。
代码
(define make-tswb
(lambda ()
(let ((records '()))
(lambda (command . args)
(cond
((equal? command 'empty?)
(null? records))
((equal? command 'add!)
(set! records (cons (car args) records)))
((equal? command 'get)
(letrec ((sort-records (lambda (r) (sort r (lambda (x y) (<= (car x) (car y)))))))
(if (null? args)
(sort-records records)
(sort-records (filter(car args) records)))))
((equal? command 'analytic)
(cond
((= (length args) 1)
((car args) records))
((= (length args) 2)
((car args) (filter (cadr args) records))))))))))
(define listofVal
(lambda (lst)
(if (null? lst)
'()
(sort (map cadddr lst) <))))
(define median
(lambda (medianList)
(let ((values (listofVal medianList)))
(let ((len (length medianList)))
// ??????????
(define tswb (make-tswb))
(tswb 'add! '(2 123 "temp1" 76.1))
(tswb 'add! '(1 123 "temp1" 72.0))
(tswb 'add! '(1 123 "temp1" 75.0))
(tswb 'analytic median)
根据this page,你需要处理两种情况:
- 列表的长度为偶数。
- 不是偶数
第一种情况,需要取中间的两个值,求和再除以二。对于第二种情况,你需要找到排序列表的中间值,这个值将是中位数。
所以,我认为这对你有用:
(define (count-median-for-even len listOfVal)
(/ (+ (list-ref listOfVal (round (- (/ len 2) 1)))
(list-ref listOfVal (round (/ len 2)))) 2))
(define (count-median-for-odd len listOfVal)
(list-ref listOfVal (round (/ len 2))))
(define median
(lambda (medianList)
(let ((values (listofVal medianList)))
(let ((len (length medianList)))
(if (even? len) (count-median-for-even len values) (count-median-for-odd len values))))))
在上面 link 的三个测试用例上测试了这个,我可以说这一定能满足你的需求。