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中返回一个数字的阶乘

这是当前不起作用的代码,有人能告诉我哪里出了问题以及如何纠正吗?我刚开始学习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 = $?"
#/猛击/宾语
阶乘()
{
设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个数字。因此bash
return
范围是
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"