bash bash中的递归函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9682524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Recursive function in bash
提问by FinalDestiny
I want to do a function that will return the factorial of a number in bash
我想做一个函数,它会在 bash 中返回一个数字的阶乘
Here's the current code that doesn't work, can anyone tell me what's wrong and how to correct it? I just started learning bash and I don't know that much.
这是当前无效的代码,谁能告诉我出了什么问题以及如何纠正它?我刚开始学习 bash,我知道的不多。
#!/bash/bin
factorial()
{
let n=
if (( "$n" <= "1" ))
then return 1
else
factorial n-1
return $n*$?
fi
return 0
}
factorial 5
echo "factorial 5 = $?"
回答by Daniel Voina
There are several syntax and a quite obvious logic one (return 0)
有几种语法和一个很明显的逻辑(返回0)
A working version is below:
一个工作版本如下:
#!/bin/bash
factorial()
{
if (( <= 1 )); then
echo 1
else
last=$(factorial $(( - 1 )))
echo $(( * last ))
fi
}
factorial 5
You are missing:
你不见了:
return is bad (should use
echo
)shbang line (is /bin/bash not /bash/bin)
Can't do arithmetic outside of
(( ))
or$(( ))
(orlet
, but(( ))
is preferred)
退货不好(应该使用
echo
)shbang 行(是 /bin/bash 不是 /bash/bin)
不能在
(( ))
or$(( ))
(或let
,但(( ))
最好)之外进行算术运算
回答by user1070300
#!/bin/bash
function factorial()
{
if (( < 2 ))
then
echo 1
else
echo $(( * $(factorial $(( - 1 ))) ))
fi
}
This will work better.
这样效果会更好。
(It works up to 25, anyway, which should be enough to prove the point about recursion.)
(无论如何,它最多可以工作到 25,这应该足以证明关于递归的观点。)
For higher numbers, bc would be the tool to use, making the ninth line above:
对于更高的数字, bc 将是使用的工具,使上面的第九行:
echo " * $(factorial $(( - 1 )))" | bc
but you have to be a bit careful with bc --
但是你必须对 bc 小心一点——
$ factorial 260
38301958608361692351174979856044918752795567523090969601913008174806\
51475135399533485285838275429773913773383359294010103333339344249624\
06009974551133984962615380298039823284896547262282019684886083204957\
95233137023276627601257325925519566220247124751398891221069403193240\
41688318583612166708334763727216738353107304842707002261430265483385\
20637683911007815690066342722080690052836580858013635214371395680329\
58941156051513954932674117091883540235576934400000000000000000000000\
00000000000000000000000000000000000000000
was quite a strain on my poor system!
对我糟糕的系统造成了很大的压力!
回答by kojiro
echo
-ing a result may be the only way to get a result for n > 5, but capturing the echo'ed result requires a subshell, which means the recursion will get expensive fast. A cheaper solution is to use a variable:
echo
-ing 结果可能是获得 n > 5 结果的唯一方法,但是捕获回显的结果需要一个子外壳,这意味着递归会很快变得昂贵。更便宜的解决方案是使用变量:
factorial() {
local -i val=${val:-()}
if (( <= 1 )); then
echo $val
return
fi
(( val *= - 1 ))
factorial $(( - 1 ))
}
If you want to be extra sure that val
is unset when you start, use a wrapping function:
如果您想val
在开始时更加确定未设置,请使用包装函数:
factorial() {
local -i val=
_fact() {
if (( <= 1 )); then
echo $val
return
fi
(( val *= - 1 ))
_fact $(( - 1 ))
}
_fact
}
For comparison:
比较:
# 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
回答by Sayan Roy Subho
clear cat
fact()
{
i=
if [ $i -eq 0 -o $i -eq 1 ]
then
echo 1
else
f=`expr $i \- 1`
f=$(fact $f)
f=`expr $i \* $f`
echo $f
fi
}
read -p "Enter the number : " n
if [ $n -lt 0 ]
then
echo "ERROR"
else
echo "THE FACTORIAL OF $n : $(fact $n) "
fi
回答by Andrii Kovalchuk
Another one implementation using echo
instead of return
另一种使用echo
代替的实现return
#!/bin/bash
factorial()
{
if [ -le 1 ]
then
echo 1
else
echo $[ * `factorial $[-1]` ]
fi
}
echo "factorial = " `factorial `
回答by Marc Dechico
#-----------------factorial ------------------------
# using eval to avoid process creation
fac=25
factorial()
{
if [[ -le 1 ]]
then
eval =1
else
factorial $[-1]
typeset f2
eval f2=$
((f2=f2*))
eval =$f2
fi
}
time factorial $fac res
echo "factorial =$res"