在 bash 中仅使用 1 个变量使用递归打印斐波那契数列

Print Fibonacci series using recursion in bash with only 1 variable

我想知道如何在 bash 中仅使用 1 个变量使用递归打印斐波那契数列。

根据我所做的:

fib()
    {
    i=
    if (( $i <= 1 ))
    then echo 0
    elif (( $i == 2 ))
    then echo 1
    else

    echo $(( $(fib $(($i - 1)) ) + $(fib $(($i - 2)) ) ))

fi
 }

echo $(fib )

我得到了最终迭代的正确输出,例如,如果我输入 10,我将得到 34,但我想打印整个数字序列,即所有迭代。我怎样才能做到这一点?

我尝试的另一种方法是:

#!/bin/bash
arr[0]=0
arr[1]=1

for (( i=0; i<=10; i++ ))
do
    echo -n "${arr[0]} "
    arr[0]=$((${arr[0]} + ${arr[1]} ))
    arr[1]=$((${arr[0]} - ${arr[1]} ))
done
echo ""

但显然我在这里使用了一个for循环,但我不想使用另一个变量。

bash 中的变量默认是全局的。您需要将 i 显式设为本地。

 fib () {
     local i
     i=
     if (( i <= 1 )); then
         echo $i
     else
         echo $(( $(fib $((i-1)) ) + $(fib $((i - 2)) ) ))
     fi
}

(此外,如果您从 0 开始,您的基本情况会有点偏离,并且 2 不必是基本情况;fib 2 可以从基本情况 fib 0fib 1.)

如果你想打印从 1 到 $n 的每个斐波那契值,我建议:

fib_r() {
    local i=
    if (( i < 0 )); then
        echo "Error: negative numbers not allowed" >&2
        exit 1

    elif (( i <= 1 )); then
        echo $i

    else
        echo $(( $($FUNCNAME $((i - 1)) ) + $($FUNCNAME $((i - 2)) ) ))
    fi
}

fib() {
    local i
    for (( i = 1; i <= ; i++ )); do
        fib_r $i
    done
}

fib 10

产出

0
1
1
2
3
5
8
13
21
34

它仍然是一个变量,尽管每个函数一个。

我在递归函数中使用了 bash 变量 $FUNCNAME ,因此您不必在函数名称中硬编码函数名称。当我重命名该函数时,我没有更新那行,这让我有点生气。


当然,如果缓存结果,您的性能会大大提高:"fib 16" 在我的 VM 上,不缓存大约需要 3.5 秒,缓存大约需要 0.03 秒.

fib_r() {
    local i=
    if (( i < 0 )); then
        echo "Error: negative numbers not allowed" >&2
        exit 1

    elif [[ -n ${fib_cache[i]} ]]; then
        echo "${fib_cache[i]}"

    elif (( i <= 1 )); then
        echo $i

    else
        echo $(( $( $FUNCNAME $((i - 1)) ) + $( $FUNCNAME $((i - 2)) ) ))
    fi
}

fib_cache=()

fib() {
    local i
    for ((i=1; i<=; i++)); do
        fib_cache[i]=$(fib_r $i)
        echo "${fib_cache[i]}"
    done
}

只是为了(我的)乐趣,此代码使用不使用变量的递归函数打印从第 0 位到第 92 位的斐波那契数(如 Fibonacci number - Wikipedia 中所定义):

#! /bin/bash

function fib
{
    echo ${3-0}

    (( > 0)) && fib $((-1)) ${3-0} $((${2-1}+${3-0}))
}

fib 92

有些人可能会声称使用位置参数(</code>、<code></code>)是作弊,但其他解决方案可以说是使用两个变量( <code>$i).

代码在我的(旧的)Linux 机器上 运行 不到 0.01 秒。

该代码应该可以在任何平台上使用 Bash 版本 3 或更高版本处理最多 92 个数字。参见 Bash Number Limit?。大于 93 的数字将导致代码因算术溢出而产生垃圾结果。