Bash脚本 - 斐波那契

时间:2015-03-26 05:52:06

标签: linux bash shell fibonacci

我试图制作一个递归函数,可以计算输入数字的斐波纳契,这是因为我不知道如何获得递归所获得的值。

#!/bin/bash

#Function - Fibonacci
fib()
{

  number=$1

  if (( number < 2 ))
    then
      (( tmp = number ))
  else
      ((--number))
      term1=$(fib $number)

      ((--number))
      term2=$(fib $number)

      (( tmp = $(( term1 + term2 )) )) #Problem is here

  fi

  (( result = $result + tmp ))
  return $result

}

#Main Program.
fib $1
  echo fib $1 = $?

有人可以帮助我吗?

6 个答案:

答案 0 :(得分:0)

我相信你知道&#34;用递归编码FIBONACCI并不是一个好主意&#34;。

递归Fib() - &gt; O(2 ^ N)
迭代的Fib() - &gt;为O(n)

请参阅this youtube video

答案 1 :(得分:0)

我运行了你的代码,我发现当数字小于2时数字不会被返回。它不断递减数值并继续寻找负数的斐波纳契数。也许这就是它给出奇怪结果的原因(这是在应用Armali给出的修复之后)。

我不确定这些算术运算的语法是否正确,因为您还在从方法中添加结果的行中指出。

查看此链接,该链接显示bash中的递归函数,但它会打印值而不是返回。 http://tldp.org/LDP/abs/html/recurnolocvar.html

我的理解是,在bash递归脚本中处理局部变量的方式存在一些问题。我看到当函数在第二次递减之后第二次调用时,第一次调用的返回值覆盖了原始数值,导致负数,因此结果很奇怪。必须有一些其他方法来处理递归调用中的返回值。

答案 2 :(得分:0)

您的代码存在一些问题。您不能将$((...))用于任何有用的算术,因为数字包围在255处。嵌入的#!/bin/bash fib() { local number term1 term2 # Avoid leaking to main scope number=$1 if ((number < 2)) then ((tmp=number)) else ((--number)) term1=$(fib "$number") ((--number)) term2=$(fib "$number") ((tmp=term1+term2)) fi ((result=result+tmp)) printf '%s\n' "$result" } #Main Program. fib "$1" # Quote argument properly! 根本没用 - 您已经在双括号内的算术上下文中。

((

))算术括号$内,您不需要变量前面的#!/bin/bash fib2() { local f ((f=$1+$2)) printf '%i %i\n' "$f" "$1" } fib() { local i j j=$1 shift for((i=1; i<j; ++i)); do set -- $(fib2 ${1-1} ${2-0}) done printf '%s\n' "${1-$i}" } #Main Program. fib "$1" ;它是无害的,但你应该尽量保持一致。

与任何天真的斐波那契实施一样,这是非常低效的。在辅助函数中计算序列的头部一次会更聪明,然后拉出最终结果并显示它。

foreach (var order in orders.GroupBy(f => f.OrderId))
{
   var strOrderId = order.Key;
   var strNames = string.Join(", ", order.Select(f => f.Name));
   Console.Writeline("{0} contains {1} ", strOrderId, strNames);
}

答案 3 :(得分:0)

关于三人间的回答:这可以更快地完成。

我认为helper函数调用确实很昂贵。低于版本的版本在2.344秒时计算出100000 fib,而辅助功能版本的结果在1min 28.44秒时发生了变化。虽然,您只能得到正确的斐波那契数,直到92 fib,但对我来说,在93 fib,您已经达到了intmax_t设置。

fibnorec(){
    # typecheck                                                                                           
    if [[ ! "$1" =~ ^[0-9]+$ ]]
    then
        return 1
    fi

    # make arg into int                                                                                   
    declare -i n="$1"

    # Return fibonacci number at index n...                                                               
    if [[ $n -le 1 ]]
    then
        # index 0 and index 1 are numbers 0 and 1 respectively.
        printf '%s\n' $n;
    fi
    # For index 2 and up (position 3 and up)
    declare -i sum=1;
    declare -i prev=1;
    for ((i=2; i<n; i++))
    do
        declare -i save=$sum;
        sum+=$prev;
        prev=$save;
    done
    printf '%s\n' $sum
}
time fibnorec 100000

答案 4 :(得分:-1)

尝试这种方法:

fn() {
    echo 'returnValue';
}

echo `fn`;

答案 5 :(得分:-1)

  

我遇到了如何获取递归所获得的值。

你已经在脚本的最后一行 - $?了。 只需在fib中执行相同操作 - 替换

      term1=$(fib $number)
      …
      term2=$(fib $number)

      fib $number; term1=$?
      …
      fib $number; term2=$?

仍然你的脚本返回奇怪的值,但你肯定可以从这里恢复。 (set -x可能会有所帮助。)