我正在尝试编写一个斐波那契函数,该函数将输入 int 作为序列长度。这是我的代码:
function fib {
local len=$1
echo "len = $len"
local arr=(0 1 1)
if [[ $len -le 3 ]]
then
echo ${arr[@]:0:$len}
let arr=${arr[@]:0:$len}
echo $arr
else
while [[ ${#arr[*]} -lt $len ]]
do
local sum=${arr[${#arr[*]}]}+${arr[${#arr[*]}-1]}
let arr+=$sum
echo "curren len = ${#arr[*]}"
done
fi
echo "arr = $arr"
}
这是我调用该函数时得到的结果:
👉👉👉 fib 2
len = 2
0 1
0
arr = 0
👉👉👉 fib 3
len = 3
0 1 1
0
arr = 0
暂时有效的话请忽略。为什么我在简单回显时得到正确的序列?但不是当我
let arr=
?
你需要通读
man bash
中关于扩展的又长又无聊的一章,它展示了数组是如何使用的。 "${array[@]}"
将数组的值扩展为单独的标记。 "${!array[@]}"
将数组的索引(或键)扩展为单独的标记。使用 *
代替 @
会生成一个字符串,由 $IFS
中的第一个字符分隔。将数组变量扩展为标量 ("$array"
) 会产生 "${array[0]}"
,它可能存在也可能不存在,因为索引数组是稀疏的并且可能不包含 [0]
元素,而关联数组可能包含也可能不包含 ['0']
钥匙。下面的代码片段还展示了 Bash 提供的出色的“调试”扩展。 (寻找@A
。)
generate_fibonacci_sequence() {
local -i counter="$1"
local -n _output_array="$2" # declare -ai
local -i a=0 b=1
_output_array=()
for ((;;)); do
((! counter--)) && return || :
_output_array+=(a)
((a += b))
((! counter--)) && return || :
_output_array+=(b)
((b += a))
done
}
declare -ai sequence
for length in {0..20}; do
generate_fibonacci_sequence "$length" 'sequence'
printf '%s\n%s %s %s\n' "${length@A}" "${sequence[@]@A}"
printf '['
for i in "${!sequence[@]}"; do
printf '(%d:%d)' "$i" "${sequence[i]}"
done
printf ']\n\n'
done
输出开始:
length='0'
declare -ai sequence=()
[]
length='1'
declare -ai sequence=([0]="0")
[(0:0)]
length='2'
declare -ai sequence=([0]="0" [1]="1")
[(0:0)(1:1)]
length='3'
declare -ai sequence=([0]="0" [1]="1" [2]="1")
[(0:0)(1:1)(2:1)]
length='4'
declare -ai sequence=([0]="0" [1]="1" [2]="1" [3]="2")
[(0:0)(1:1)(2:1)(3:2)]
length='5'
declare -ai sequence=([0]="0" [1]="1" [2]="1" [3]="2" [4]="3")
[(0:0)(1:1)(2:1)(3:2)(4:3)]
length='6'
declare -ai sequence=([0]="0" [1]="1" [2]="1" [3]="2" [4]="3" [5]="5")
[(0:0)(1:1)(2:1)(3:2)(4:3)(5:5)]
length='7'
declare -ai sequence=([0]="0" [1]="1" [2]="1" [3]="2" [4]="3" [5]="5" [6]="8")
[(0:0)(1:1)(2:1)(3:2)(4:3)(5:5)(6:8)]
...
无论如何,请注意,Bash 在底层使用带符号的 64 位整数,其下溢/溢出行为在(例如)C++ 中将被视为“未定义”:
$ echo $((2**63))
-9223372036854775808
$ echo $((2**63 - 1))
9223372036854775807
话虽如此,在 Python 中计算大型斐波那契数可能会更好,因为它在底层使用了 GNU MP。 (或者直接使用GNU MP。)