2016-03-27 22 views
0

文字列に保存された値の中央値を見つける必要があります。私は追加の一時ファイルなしでこれをbashで実装する必要があります。 awkを使用できません。値の文字列から中央値を取得

85 13 4 45 1111 89 87 66 1 5 2 51 13 66 98 50 20 14 18 16 31 21 5175 12 

はまず、私はこのように、これらの値をソートする必要があります:

私は、この文字列が$stringに保存されてい

1 2 4 5 12 13 13 14 16 18 20 21 31 45 50 51 66 66 85 87 89 98 1111 5175 

をそして私は、これらの値の中央値を見つける必要があり

(21+31)/2 = 26 

どうすればこの問題を解決できますか? bashには効率的な方法やコマンドがありますか?

私の考え:

値をソートするために、私はsortを使用することができますが、私はそれがファイルを使用しているため、文字列から値をソートするためにそれを強制するかどうかはわかりません。

私は中央値をどのように達成するのか考えていないので、少なくとも私は小さなヒントに感謝します。あなたは、次のようなコマンドを使用することができます

答えて

1

を、あなたは、別の行に各それらを印刷sort -nにパイプして、配列に読み込むことができますmapfileで:

string='85 13 4 45 1111 89 87 66 1 5 2 51 13 66 98 50 20 14 18 16 31 21 5175 12' 
mapfile -t arr < <(for num in $string; do echo "$num"; done | sort -n) 

-tオプションは、各値から改行を削除します。 mapfileへのパイプはにできません。サブシェルにあり、その後はarrが空になるためです。

通常は変数を引用することをお勧めしますが、この場合は単語分割に頼っており、$stringを引用してはいけません。

  • あり、配列要素の数が奇数であり、我々はちょうど真ん中の要素の値をしたい:

    は今、中央値のために、2つのオプションがあります。

  • 偶数の配列要素があり、2つの中間要素の平均が必要です。

配列の要素数が${#arr[@]}あるので、我々はそれをチェックして、何をすべきかを決定することができます

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" 

これは、整数算術演算に依存している:私たちは奇数の要素を持っている場合は、3を言います中央値のインデックスは、1の整数除算から得られる1 –です。偶数の要素、たとえば4つの要素については、インデックス1と2の要素を必要とします。これは、高いインデックスの場合は4つを2つに分割し、低いインデックスの場合は1つを減算して取得します。

2つの要素が偶数になっていない場合、結果は切り捨てられます。これで十分でない場合は、数値が奇数かどうかを確認し、結果に.5を手動で追加するか、またはbcを使用して計算を行うことができます。検討:

$ echo $((11/2)) 
5 
$ bc <<< 'scale=1; 11/2' 
5.5 
1

:ソートされた配列に文字列から数値を取得するには

str="85 13 4 45 1111 89 87 66 1 5 2 51 13 66 98 50 20 14 18 16 31 21 5175 12" 
count=$(echo $str | wc -w) 
arr=($(echo $str | tr " " "\n" | sort -n)) 
#echo ${arr[*]} 

if [[ $(($count % 2)) == 0 ]]; then 
    # even element count, get the elements around the middle 
    f1=${arr[ $(((count - 1) /2)) ]} 
    f2=${arr[ $(((count + 1) /2)) ]} 
    #echo "f1=$f1, f2=$f2" 
    echo $((($f1 + f2)/2)) 
else 
    # odd element count 
    echo ${arr[ $(($count/2))]} 
fi 
関連する問題