提问人:ToegapBananaboat 提问时间:11/14/2023 更新时间:11/14/2023 访问量:59
我的变量赋值有什么问题?
What's wrong with my variable assignment?
问:
我正在尝试编写一个斐波那契函数,该函数将输入 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=
答:
3赞
Andrej Podzimek
11/14/2023
#1
您需要通读 中关于扩展的冗长而无聊的章节,其中显示了如何使用数组。 将数组的值扩展为单独的标记。 将数组的索引(或键)扩展为单独的标记。使用 instead 会生成一个字符串,该字符串由 中的第一个字符分隔。将数组变量扩展为标量 () 会产生 ,它可能存在也可能不存在,因为索引数组是稀疏的,可能不包含元素,而关联数组可能包含也可能不包含键。下面的代码片段还显示了 Bash 提供的漂亮的“调试”扩展。(查找 .)man bash
"${array[@]}"
"${!array[@]}"
*
@
$IFS
"$array"
"${array[0]}"
[0]
['0']
@A
generate_fibonacci_sequence() {
local -i counter="$1"
local -n _output_array="$2" # declare -ai
_output_array=()
((counter)) || return 0
local -i a=0 b=1
for ((;;)); do
_output_array+=(a)
((--counter)) || return 0
((b += a))
_output_array+=(b)
((--counter)) || return 0
((a += b))
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 中计算大斐波那契数可能会更好,Python 在后台使用 GNU MP。(或者直接使用 GNU MP。
评论
arr+=($sum)
let
let
let
用于计算算术表达式。当只是附加时,你真的不希望这样。计算总和可能应该是 1。( expr ))。