bash中的递归函数
我想做一个函数,在bash中返回一个数字的阶乘 这是当前不起作用的代码,有人能告诉我哪里出了问题以及如何纠正吗?我刚开始学习bash,我知道的不多bash中的递归函数,bash,function,recursion,Bash,Function,Recursion,我想做一个函数,在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 = $?" #/猛击
#!/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 = $?"
#/猛击/宾语
阶乘()
{
设n=1美元
if(“$n”有几种语法和一种非常明显的逻辑(返回0)
工作版本如下:
#!/bin/bash
factorial()
{
if (( $1 <= 1 )); then
echo 1
else
last=$(factorial $(( $1 - 1 )))
echo $(( $1 * last ))
fi
}
factorial 5
!/bin/bash
阶乘()
{
如果($1
但是你必须对bc有点谨慎--
对我糟糕的系统来说是一个很大的压力!另一个实现使用echo
而不是return
#!/bin/bash
factorial()
{
if [ $1 -le 1 ]
then
echo 1
else
echo $[ $1 * `factorial $[$1-1]` ]
fi
}
echo "factorial $1 = " `factorial $1`
echo
-获取n>5的结果可能是唯一的方法,但捕获echo'ed结果需要一个子shell,这意味着递归将很快变得昂贵。更便宜的解决方案是使用变量:
factorial() {
local -i val=${val:-($1)}
if (( $1 <= 1 )); then
echo $val
return
fi
(( val *= $1 - 1 ))
factorial $(( $1 - 1 ))
}
作为比较:
# 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
返回码是一个单字节,因此会中断n>5。要解决此问题,您需要将函数更改为回显结果,而不是将返回码+1和+9000设置为@tripleee。bash中的函数应该回显结果,而不是返回结果。$[…]
语法已经被弃用了几十年。停止使用它。@Osirisgottra:在数学中,一个非负整数n的阶乘,用n!表示,是所有小于或等于n的正整数的乘积。不过你的评论是有效的-很难摆脱我在过去20年中习惯的习惯用法…@tripleee a byte是8位或2^8个数字。因此bashreturn
范围是0-255
(2^8-1)。但我同意,仍然应该避免返回,并用echo替换。-1:这只是使用不推荐的语法重写@user1070300的答案。为什么if下的echo 1不打印一个并作为返回类型?我发现您的方法将调用与$1一样多的子shell,这不是必需的,而且效率很低。如何避免e子shell的创建?@TorosFanny你是对的,这可以重写以避免子shell的创建。这里有一个很好的答案:谢谢你的评论,它帮助我学到了一些新的东西!合理的建议。不过,如果你没有使用随机输入,你的测量结果会更令人信服。据我们所知,你的方法有100次计数关于阶乘(1),而另一个做了100次阶乘(20):)我喜欢使用变量,这是一个很好的例子,说明了如何以及为什么使用变量。如果你真的怀疑随机变量能给出令人信服的结果,你自己尝试这个实验很容易。我想找到一种方法,将eval整合到计算公式中((eval…)
#!/bin/bash
factorial()
{
if [ $1 -le 1 ]
then
echo 1
else
echo $[ $1 * `factorial $[$1-1]` ]
fi
}
echo "factorial $1 = " `factorial $1`
factorial() {
local -i val=${val:-($1)}
if (( $1 <= 1 )); then
echo $val
return
fi
(( val *= $1 - 1 ))
factorial $(( $1 - 1 ))
}
factorial() {
local -i val=$1
_fact() {
if (( $1 <= 1 )); then
echo $val
return
fi
(( val *= $1 - 1 ))
_fact $(( $1 - 1 ))
}
_fact $1
}
# 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
clear cat
fact()
{
i=$1
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
#-----------------factorial ------------------------
# using eval to avoid process creation
fac=25
factorial()
{
if [[ $1 -le 1 ]]
then
eval $2=1
else
factorial $[$1-1] $2
typeset f2
eval f2=\$$2
((f2=f2*$1))
eval $2=$f2
fi
}
time factorial $fac res
echo "factorial =$res"