首页 > 解决方案 > 在 tcl 中查找列表的中位数和平均值

问题描述

我很难找到一种方法来计算数字列表的中位数和平均值,并且在线资源似乎真的受到 Tcl 的限制。到目前为止,我设法只打印了列表的数字。

您的帮助将不胜感激。

proc ladd {l} {
    set total 0
    set counter 0
    foreach nxt $l {
        incr total $nxt
        incr counter 1
    }
    puts "$total"
    puts "$counter"

    set average ($total/$counter)

    puts "$average"


}

set a [list 4 3 2 1 15 6 29]
ladd $a

标签: tcl

解决方案


要获得列表的平均值(即算术平均值),您可以这样做:

proc average {list} {
    expr {[tcl::mathop::+ {*}$list 0.0] / max(1, [llength $list])}
}

将列表中的值相加(尾随0.0强制结果为浮点值,即使所有相加的数字都是整数)并除以元素的数量(如果列表为空,则为 1,因此空列表获得平均值为 0.0 而不是错误)。

要获得列表的中位数,您必须对其进行排序并选择中间元素。

proc median {list {mode -real}} {
    set list [lsort $mode $list]
    set len [llength $list]
    if {$len & 1} {
       # Odd number of elements, unique middle element
       return [lindex $list [expr {$len >> 1}]]
    } else {
       # Even number of elements, average the middle two
       return [average [lrange $list [expr {($len >> 1) - 1] [expr {$len >> 1}]]]
    }
}

为了完成这个集合,如果有一个唯一的集合,这里是如何获取列表的模式(与从相当小的集合中选择值的某些应用程序相关):

proc mode {list} {
    # Compute a histogram
    foreach val $list {dict incr h $val}
    # Sort the histogram in descending order of frequency; type-puns the dict as a list
    set h [lsort -stride 2 -index 1 -descending -integer $h]
    # The mode is now the first element
    return [lindex $h 0]
}

我将把处理空的和非唯一的案例作为练习。


推荐阅读