我试图建立一个递归函数来计算Fibonnaci级数的第n个数。我已经找到了很多解决这个问题的方法,但是我想知道为什么我的方法不起作用。谢谢。

function fib ()
{
        if [ $1 -eq 1 -o $1 -eq 2 ]
        then
                return 1
        else
               let nr=$1-1
               fib $nr
               rez1=$?
               let nr=$1-2
               fib $nr
               rez2=$?
               let rez=$rez1+$rez2
               return $rez
        fi
}

最佳答案

这里有两个问题。首先,所有变量都是全局变量,这意味着当您进行递归调用时,它会覆盖nrrezrez1rez2的值。您可以通过将它们声明为local来解决此问题:

fib() {
    local nr rez rez1 rez2
    if [ $1 -eq 1 -o $1 -eq 2 ]; then
        return 1
    else
        let nr=$1-1
        fib $nr
        rez1=$?
        let nr=$1-2
        fib $nr
        rez2=$?
        let rez=$rez1+$rez2
        return $rez
    fi
}

第二个问题是,您试图通过函数的返回状态传递一个数字。返回状态是一个1字节的无符号整数,这意味着它不能大于255(在255之后,它将返回0)。它的真正目的是给出成功/失败的结果(可能还有一些关于失败的信息),0表示成功,其他任何信息都表示错误。想把它用在别的事情上是自找麻烦。您可以在这里看到结果(从函数的localized版本):
$ fib 11; echo $?
89
$ fib 12; echo $?
144
$ fib 13; echo $?
233
$ fib 14; echo $?
121

第14个斐波那契数是377,但超过了255,所以它是377-256=121。要解决此问题,请将结果返回到stdout,并用echo捕获它:
fib() {
    local nr rez rez1 rez2
    if [ $1 -eq 1 -o $1 -eq 2 ]; then
        echo 1
    else
        let nr=$1-1
        rez1=$(fib $nr)
        let nr=$1-2
        rez2=$(fib $nr)
        let rez=$rez1+$rez2
        echo $rez
    fi
}

……不过,这确实有一个缺点:它要慢得多,因为对$( )的每个调用都必须作为子进程运行,并且创建子进程在计算上非常昂贵。(这实际上解决了全局变量问题,因为变量向下继承到子流程,而不是向上继承;但它只是偶然地解决了这个问题。)
带回家的教训:shell脚本不是这样的语言。

关于bash - 生成斐波那契数列的Shell脚本,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42987607/

10-13 08:59