スペースで区切られた1行の整数を追加し、絶対値を見つけようとします。 5つの整数があり、そのうちの1つは負で、もう1つは正です。すべての数値の絶対値がわかるように、現在の負の値を正にする方法を見つけたいと思います。これが私が今まで持っているものです。
read input
# 1, 5, -17, 32, 12
# expected absolute value: 67
absolute_value()
{
local absolute_value=0
for nums in $input;
do
((absolute_value += nums))
done
echo $absolute_value
}
absolute_value
私の答えは33で、予想される答えは67でした。もちろん、追加されますが、入力数字の1つが負数である可能性があるため、絶対値ではなく合計を提供します。混乱して答えを探していますが、わかりません。 Bashは私の最も強力な言語ではないので、おそらく無視するでしょう。
答え1
まあ、どうですか?絶対値定義?
if [ "$num" -lt 0 ]; then
num=$((-num))
fi
とにかく、これは:
for nums in $input
噴射に依存し、少し醜いです。誰かが数字以外の文字やグローバル文字を入力すると、興味深い効果も得られます。 Bashを使用しているので、値read -a
を[[ var -lt 0 ]]
。
しかし、単にこれを行うのは良いことではありません。 Bashの算術拡張は危険だからです。コマンドは配列索引付けとコマンド置換によって簡単に注入でき、シェルはそれを実行します。したがって、最初に受信した値が数値であることを確認する必要があります。
#!/bin/bash
read -a nums
sum=0
for a in "${nums[@]}"; do
if [[ $a = *[^-0-9]* ]]; then
echo "invalid number: $a"
exit 1
fi
if [[ a -lt 0 ]]; then
sum=$((sum + -a))
else
sum=$((sum + a))
fi
done
echo "$sum"
0
Bashは、で始まる数字をそれぞれ8進数と16進数として解釈します0x
。
あるいは、実際のプログラミング言語を使用すると、すべての操作を手動で実行する必要はありません。
$ python3 -c 'print(sum(map(lambda x: abs(int(x)), str.split(input()))))'
1 5 -17 32 12
67
答え2
パラメータ置換を使用してマイナス記号を削除できます。
入力を読む #1、5、-17、32、12 #絶対値期待:67 絶対値(){ 地域絶対値=0 $input の数値については、次のようにします。 ((絶対値+ =${nums#-})) 完璧 エコ$絶対値 } 絶対値
forループを使用したくない場合は、以下を試してください。
printf "%s\n" ${input/-/} | awk '{ sum += $1 } END { print sum }'
私はwhileループと配列を使用してユーザーが実行できる入力の量を制御し、入力が間違っているかどうかを尋ねます。
declare -a arr
declare -a arr_abs
echo "Enter four numbers:"
while true; do
read num
[[ $num =~ ^[^-0-9]$ ]] && echo "Not a number..." && continue
# keep the original values for any other use
arr+=($num)
# create an array with absolute values
arr_abs+=(${num#-})
[[ ${#arr[@]} -eq 4 ]] && break
done
absolute_value() {
sum=$(printf "%s\n" ${arr_abs[@]} | awk '{ sum += $1 } END { print sum }')
echo "The absolute sum is $sum"
}
absolute_value