2

我正在仔细阅读代码以获得一些帮助,并在大约 4 个月前遇到了一个线程,但是用户的最终修订版在发布到 bash 时不起作用,并产生了一些奇怪的结果。这是我的版本,它也会产生一些奇怪的结果:

#!/bin/bash
fib()
{
ind=$1

if (( ind <= 0 ))
 then echo 0
elif (( ind = 1 ))
 then echo 1
else
  echo $(( $(fib $((ind - 1)) ) + $(fib $((ind - 2)) ) )) 
fi
}
echo fibbonacci sequence number $1 is $(fib $1)

所以这段代码最终总是输出 1。./fib.sh 5 输出斐波那契序列号 5 是 1

所以我试着把代码写得更接近前一个提问者的代码,

#!/bin/bash

fib()
 {
  ind=$1

if (( ind <= 0 ))
 then echo 1
else
  echo $(( $(fib $((ind - 1)) ) + $(fib $((ind - 2)) ) )) 
fi
 }
 echo fibbonacci sequence number $1 is $(fib $1)

虽然我不明白这里的逻辑,但它实际上开始输出斐波那契数,但现在我遇到了一个稍微不同的问题;./fib.sh 3 输出:斐波那契序列号 3 是 5 ./fib.sh 5 输出:斐波那契序列号 5 是 13 我们知道第 3 个斐波那契数是 1,而第 5 个是 3 那么给出了什么?该代码似乎跳过了几个斐波那契数,我无法弄清楚我的代码在逻辑上是什么错误。

4

4 回答 4

2

通常在编写斐波那契序列逻辑时,您必须对前两个数字进行特殊处理。这就是第一个用户所做的:特殊大小写 0 和 1。

您已经删除了一个特殊情况的实例,并将所有内容都移动了一个索引,这解释了一次移动。另一个很简单:代码是零索引的。这就是为什么一切都“差两点”。

原始代码有什么问题?这一行:

elif ((ind = 1))

ind 设置为 1。否则没关系。

对您的代码的一个简单修复是替换此行:

if (( ind <= 0 ))

if (( ind <= 2 ))

然后你就走了。这为您提供了您期望的单索引行为:

cternus@astarael ~/foo> for i in `seq 1 10`; do ./foo.sh $i; done
fibbonacci sequence number 1 is 1
fibbonacci sequence number 2 is 1
fibbonacci sequence number 3 is 2
fibbonacci sequence number 4 is 3
fibbonacci sequence number 5 is 5
fibbonacci sequence number 6 is 8
fibbonacci sequence number 7 is 13
fibbonacci sequence number 8 is 21
fibbonacci sequence number 9 is 34
fibbonacci sequence number 10 is 55
于 2013-10-27T22:18:45.073 回答
1
#!/bin/bash

function fib(){
    if [ $1 -le 0 ]; then
        echo 0
    elif [ $1 -eq 1 ]; then
        echo 1
    else
        echo $[`fib $[$1-2]` + `fib $[$1 - 1]` ]
    fi

}

fib $1
于 2014-04-04T07:15:29.897 回答
0
#!/bin/bash
#fibonacci sequence function
fib()
{
ind=$1

if (( ind <= 0 ))
 then echo 0
elif (( ind == 2 ))
 then echo 1
else
  echo $(( $(fib $((ind - 1)) ) + $(fib $((ind - 2)) ) )) 
fi 
}
echo fibbonacci sequence number $1 is $(fib $1)

所以我的问题是平等检查

elif (( ind = 1 ))

我应该使用双 =,并将 1 更改为 2,所以它应该是

elif (( ind == 2 )) 

最终我的正确脚本应该是这样的

#!/bin/bash
#fibonacci sequence function
fib()
{
ind=$1

if (( ind <= 1 ))
 then echo 0
elif (( ind == 2 ))
 then echo 1
else
  echo $(( $(fib $((ind - 1)) ) + $(fib $((ind - 2)) ) )) 
fi
 }
echo fibbonacci sequence number $1 is $(fib $1)

感谢 bajillion 和 Christian Ternus 的帮助,我已经编程了几年,完全应该看到平等检查错误 >.<

于 2013-10-28T13:51:54.673 回答
0

有趣的是,Korn shell 执行 @christianternus 的脚本比其他 shell 快得多:

$ for a in sh bash zsh ksh; 做回声“外壳:$ a”;$(seq 1 20) 中 i 的时间;做 $a bin/fib.sh $i; 完成 | md5sum; 完毕
外壳:sh
5fece53a38f2df040bfaf9632c2b7f4b -
实际0m29.508s
用户 0m3.788s
系统 0m11.785s

外壳:重击
5fece53a38f2df040bfaf9632c2b7f4b -
真正的 0m29.906s
用户 0m3.604s
系统 0m11.235s

外壳:zsh
5fece53a38f2df040bfaf9632c2b7f4b -
真正的 0m29.203s
用户 0m2.505s
系统 0m14.377s

外壳:ksh
5fece53a38f2df040bfaf9632c2b7f4b -
实际0m0.942s
用户 0m0.843s
系统 0m0.079s
于 2014-01-16T01:56:20.923 回答