我还没有找到任何简单的实现来查找数组的中位数。怎么能做到这一点是bash而不重新发明轮子?
如果目前使用此:
median() {
arr=$1
nel=${#arr[@]}
if (( $nel % 2 == 1 )); then # Odd number of elements
val="${arr[ $(($nel/2)) ]}"
else # Even number of elements
val="$(( ( arr[$((nel/2))] + arr[$((nel/2-1))] ) / 2 ))"
fi
printf "%d\n" "$val"
}
出于某种原因,我仍然无法弄清楚,它会返回不正确的值,而且对于这么简单的事情来说似乎过于复杂。我觉得有必要在一条线上做到这一点。
答案 0 :(得分:3)
我想你想要这样的东西:
#!/bin/bash
median() {
arr=($(printf '%d\n' "${@}" | sort -n))
nel=${#arr[@]}
if (( $nel % 2 == 1 )); then # Odd number of elements
val="${arr[ $(($nel/2)) ]}"
else # Even number of elements
(( j=nel/2 ))
(( k=j-1 ))
(( val=(${arr[j]} + ${arr[k]})/2 ))
fi
echo $val
}
median 1
median 2 50 1
median 1000 1 40 50
示例输出
1
2
45
答案 1 :(得分:0)
这对整数和分数数据都有效:
#!/bin/bash
median() {
declare -a data=("${!1}")
IFS=$'\n' sorted_data=($(sort <<<"${data[*]}"))
local num_elements=${#sorted_data[@]}
if (( $num_elements % 2 == 1 )); then # Odd number of elements
((middle=$num_elements/2))
val="${sorted_data[ $(($num_elements/2)) ]}"
else # Even number of elements
((before_middle=$num_elements/2 - 1))
((after_middle=$num_elements/2))
val=$(echo "(${sorted_data[$before_middle]} + ${sorted_data[$after_middle]})/2" | bc -l)
fi
# remove trailing zeros
echo $val | sed -r 's/\.([0-9]*[1-9])0*$/\.\1/; s/\.0*$//;'
}
median 1
median 2 50 1
median 1000 1 40 50
median 1.5 2.5
median 0.3 0.6 0.9
的产率:
1
2
45
2
0.6