フィボナッチ数列、標準入力は自然数 1<=n<=50 でなければなりません。 BASHから

フィボナッチ数列、標準入力は自然数 1<=n<=50 でなければなりません。 BASHから

私が受けたテストの問題は次のとおりです。

次の出力行で、最初の項からn番目の項(含む)までのフィボナッチ数列の次の項を作成します。フィボナッチ数列の最初の項と2番目の項はそれぞれ0と1であると仮定します。

フィボナッチ数列を生成するためにシェルコードをコピーしました(ここから)、条件文が必要です1<=n<=50が、whileループの後に追加する方法がわかりません。

function fib
{
  x=0
  y=1
  i=2
  echo "Fibonacci Series up to $n terms :"
  echo "$x"
  echo "$y"
  while [ $i -lt $n ]
  do
      i=`expr $i + 1 `
      z=`expr $x + $y `
      echo "$z"
      x=$y
      y=$z
  done
}
r=`fib $n`
echo "$r"

答え1

関数を中断するために、ループの前にこれを行うことができます。

if [[ $n -lt 1 ]] || [[ $n -gt 50 ]]
then
    return
fi

次のように入力値を制限することもできます。

if [[ $n -lt 1 ]]
then
    n=1
fi
if [[ $n -gt 50 ]]
then
    n=50
fi

最初のオプションを含むコードの作業バージョンは次のとおりです。

function fib
{
  x=0
  y=1
  i=2
  n=$1
  
  if [[ $n -lt 1 ]] || [[ $n -gt 50 ]]
  then
    return
  fi
  
  echo "Fibonacci Series up to $n terms :"
  echo "$x"
  echo "$y"
  while [[ $i -lt $n ]]
  do
      i=`expr $i + 1 `
      z=`expr $x + $y `
      echo "$z"
      x=$y
      y=$z
  done
}
r=`fib $n`
echo "$r"

答え2

bashや他のKornに似たシェルでは算術式で整理されていないデータの使用これには、ランダムなコマンド実行の脆弱性を引き起こす内部算術演算子のためのKornスタイル((...))と構成パラメータが含まれます。$((...))[[...]]

exprしばしば信頼できず、数十年が経ちました。

したがって、算術コンテキストで入力を使用する前に、入力を削除して、予想される形式の有効な数値であることを確認する必要があります。

Bash算術式では、前に0がある数字は8進数として解釈されるため、これを拒否するのが最善です。最後に、1..50以外の数字をフィルタリングするには、テキストパターンマッチングを使用する方が簡単です。

case $1 in
  ([123456789] | [1234][0123456789] | 50) ;;
  (*) echo>&2 Not a decimal integer number in the 1..50 range; exit 1
esac

答え3

最新のシェルでは、廃止された古い数学構文やバックティックを避け、読みやすさを向上させます。

#!/bin/bash

fib(){

    x=0 y=1 i=2 n=$1

    ((n < 1 || n > 50)) && return

    echo "Fibonacci Series up to $n terms :"
    echo "$x"
    echo "$y"
    while ((i++ < n)); do
        z=$((x+y))
        echo "$z"
        x=$y y=$z
    done
}

read -p 'Type an integer between 1 and 50 as max terms >>> ' n
r=$(fib $n)
echo "$r"

((...))$((...))式が0でない場合は終了ステータス0を返し、式が0の場合は1を返す算術命令です。副作用(割り当て)が必要な場合は、「let」の同義語としても使用されます。バラよりhttp://mywiki.wooledge.org/ArithmeticExpression


バックティックは、以前のスタイルのコマンド置換に使用されます。foo=$(command)代わりにこの構文を使用することをお勧めします。内部バックスラッシュ処理は$()驚くべきことではなく、$()入れ子にするのが簡単です。バラよりhttp://mywiki.wooledge.org/BashFAQ/082


expr古代のシェルコードで数学を実行するために使用されるプログラムです。 bash などの Posix シェルでは、$(( expression ))bash、ksh、mksh、pdksh、yash、dash、ash、sh、zsh を使用することもできます。(( expression ))

関連情報