シェルスクリプトで再帰関数を作成しようとしています。次のコードを考えてみましょう。
function printA {
if [[ "$1" = 0 ]]; then
return
else
echo "a$(printA $(("$1" - 1)))"
fi
}
printA 10
function factorial {
if [[ "$1" = 0 ]]; then
return 1
else
return $(( "$1" * $(factorial $(( $1 - 1 )) ) ))
fi
}
echo $(factorial 5)
コードが失敗します。
bash
(3.0)
recur.sh:行5:「10」 - 1:構文エラー:オペランドが必要です(エラーは「10」 - 1で示されています)
ㅏ
recur.sh: 行 16: "1" * : 構文エラー: オペランドが必要です (エラーは ""1" * " で示される)。
recur.sh:行16:「2」*:構文エラー:オペランドが必要です(エラーは「2」*」と表示されます)。
recur.sh: 行 16: "3"*: 構文エラー: オペランドが必要 (エラーは ""3"*" で示される)
recur.sh:行16:「4」*:構文エラー:オペランドが必要です(エラーは「4」*」と表示されます)。
recur.sh:行16:「5」*:構文エラー:オペランドが必要です(エラーは「5」*」と表示されます)。
zsh
(4.2.1)
printA:1: 無効な数学表現: 無効な文字: "
ㅏ
ファクトリアル: 5: 無効な数学表現: 無効な文字: "
しかし、部分的に正常に使用されましたksh88
。 2番目の機能だけが失敗しました。
あああああああああ
recur.sh[5]: 1 * : より多くのトークンが予想されます。
recur.sh[5]: 2 * : より多くのトークンが予想されます。
recur.sh[5]: 3 * : より多くのトークンが予想されます。
recur.sh[5]: 4 * : より多くのトークンが予想されます。
recur.sh[5]: 5 * : より多くのトークンが予想されます。
- 私は何が間違っていましたか?
- bashとzshは別の再帰構文をサポートしていますか?
- なぜ2番目の関数(
factorial
)が失敗するのですksh
か?
ポリスチレン:知っています。再帰は悪く、パフォーマンスも悪いです。代わりに通常のループを使用する必要があります。 bla bla bla.再帰が良いか悪いかを議論するのではなく、通常のシェルがそれをサポートしているかどうかを議論することです。私は単純な反復ループがトリックを実行するときに本番で再帰関数を送信するほど愚かではありません。 :)
ベストアンサー1
- 構文エラー:算術演算には引用符は使用されません。
- 論理エラー:STDOUTと値を混合しています
return
。
値をSTDOUTに渡します。
function factorial {
(( $1 )) &&
echo $(( $1 * $( factorial $(( $1 - 1 )) ) )) ||
echo 1
}
factorial 5
またはreturn
彼らは:
function factorial {
(( $1 )) || return 1
factorial $(( $1 - 1 ))
return $(( $1 * $? ))
}
factorial 5
echo $?
どちらのコードもbash
、ksh
(もちろん93、88についてはわかりません)、で動作しますzsh
。したがって、シェルは再帰をサポートします。