Fin*_*iny 30 bash recursion function
我想做一个函数,它将在bash中返回一个数字的阶乘
这是当前不起作用的代码,任何人都可以告诉我什么是错的以及如何纠正它?我刚开始学习bash,我不知道那么多.
#!/bash/bin
factorial()
{
let n=$1
if (( "$n" <= "1" ))
then return 1
else
factorial n-1
return $n*$?
fi
return 0
}
factorial 5
echo "factorial 5 = $?"
Run Code Online (Sandbox Code Playgroud)
Dan*_*ina 36
有几种语法和一个非常明显的逻辑(返回0)
下面是一个工作版本:
#!/bin/bash
factorial()
{
if [[ $1 -le 1 ]]
then
echo 1
else
last=$(factorial $[$1-1])
echo $(($1 * last))
fi
}
factorial 5
Run Code Online (Sandbox Code Playgroud)
你错过了:
如果语法不好
递归调用很糟糕
返回不好(eval语法坏了)
shbang line(/ bin/bash not/bash/bin)
use*_*300 17
#!/bin/bash
function factorial()
{
if (( $1 < 2 ))
then
echo 1
else
echo $(( $1 * $(factorial $(( $1 - 1 ))) ))
fi
}
Run Code Online (Sandbox Code Playgroud)
这会更好.
(无论如何,它最多可以工作25,这应该足以证明关于递归的观点.)
对于更高的数字,bc将是使用的工具,使上面的第九行:
echo "$1 * $(factorial $(( $1 - 1 )))" | bc
Run Code Online (Sandbox Code Playgroud)
但你必须对bc有点小心 -
$ factorial 260
38301958608361692351174979856044918752795567523090969601913008174806\
51475135399533485285838275429773913773383359294010103333339344249624\
06009974551133984962615380298039823284896547262282019684886083204957\
95233137023276627601257325925519566220247124751398891221069403193240\
41688318583612166708334763727216738353107304842707002261430265483385\
20637683911007815690066342722080690052836580858013635214371395680329\
58941156051513954932674117091883540235576934400000000000000000000000\
00000000000000000000000000000000000000000
Run Code Online (Sandbox Code Playgroud)
对我糟糕的系统来说是一种压力!
echo
-对结果进行运算可能是获得n> 5的结果的唯一方法,但是捕获回显结果需要一个子shell,这意味着递归将很快变得昂贵。较便宜的解决方案是使用变量:
factorial() {
local -i val=${val:-($1)}
if (( $1 <= 1 )); then
echo $val
return
fi
(( val *= $1 - 1 ))
factorial $(( $1 - 1 ))
}
Run Code Online (Sandbox Code Playgroud)
如果要确保val
启动时未设置该设置,请使用包装函数:
factorial() {
local -i val=$1
_fact() {
if (( $1 <= 1 )); then
echo $val
return
fi
(( val *= $1 - 1 ))
_fact $(( $1 - 1 ))
}
_fact $1
}
Run Code Online (Sandbox Code Playgroud)
为了比较:
# My Method
$ time for i in {0..100}; do factorial $(( RANDOM % 21 )); done > /dev/null
real 0m0.028s
user 0m0.026s
sys 0m0.001s
# A capturing-expression solution
$ time for i in {0..100}; do factorial $(( RANDOM % 21 )); done > /dev/null
real 0m0.652s
user 0m0.221s
sys 0m0.400s
Run Code Online (Sandbox Code Playgroud)