вместо
SAVED[$currentIndex]=$((`fib $[$currentIndex - 1]`+`fib $[$currentIndex - 2]`))
Вы, вероятно, хотели написать
SAVED[currentIndex]=$((`fib $((currentIndex - 1))` + `fib $((currentIndex - 2))`))
Однако это не решило бы реальной проблемы. Как мы видим из вашего журнала, массив памятки всегда содержит не более одной записи. Как это возможно, что последняя запись заполнена, но записи, необходимые для вычисления этой последней записи, равны 0? Ответ »подоболочки« !
Когда вы вызываете свою функцию с использованием подоболочки $(fib ...)
, изменения, которые функция вносит в переменные, находятся только внутри подоболочки.
Чтобы обойти эту проблему, вы должны либо использовать файл для запоминания, либо найти способ вызвать вашу функцию без вложенной оболочки.
Вот как я написал бы этот сценарий, если бы меня заставили использовать ваш текущий подход. Обратите внимание, что есть лучшие способы вычисления чисел Фибоначчи и лучшие языки для программирования этих вычислений.
#! /bin/bash
memo=(0 1)
fib() {
>&2 printf %s "fib($1) memo=(${memo[*]}) => "
local n="$1"
if [ "${memo[n]+x}" ]; then
>&2 echo lookup
return
fi
>&2 echo compute
fib "$((n-1))"
fib "$((n-2))"
((memo[n]=memo[n-1]+memo[n-2]))
}
fib "$1"
echo "${memo[$1]}"
Строки, начинающиеся с >&2
, предназначены только для печати отладочной информации; Вы можете удалить их. Чтобы подавить вывод отладочной информации, запустите скрипт как script.sh 12 2> /dev/null
.
Улучшения: * * тысяча двадцать-один
- Чтобы обойти проблему subshell, не отображайте результат функции и сохраняйте его, используя
var=$(fib ...)
, но храните молчание и сохраняйте результат непосредственно в назначенной глобальной переменной. Здесь нам не нужна новая переменная, потому что у нас уже есть массив памятки. Сначала мы вызываем fib x
, чтобы убедиться, что запись массива x
есть, а затем получаем доступ к этой записи с помощью memo[x]
.
- Вместо печати в журнал выведите отладочную информацию в
stderr
, используя >&2 echo
.
- Сохраняя
fib(0)=0
в массиве памятки, нам не нужно использовать смещение индекса.
- Вставить тривиальные случаи 0 и 1 непосредственно в массив памятки.
- Не инициализировать массив с
0
.
${memo[n]}+x
расширяется до x
тогда и только тогда, когда fib(n)
уже запомнено.