Я пытаюсь написать рекурсивную функцию bash для последовательности Фибоначчи. Пока у меня есть код, как показано ниже:
#!/bin/bash
Fibo() {
case $1 in
0) echo 0;;
1) echo 1;;
*) echo $[$[$Fibo $[$1-1]]+$[$Fibo $[$1-2]]] ;;
esac
}
for (( i=0; i<=$1; i++ )); do
Fibo $i
done
Вот пример вывода:
0
1
1
3
5
7
9
11
Конечно, должно быть 0 1 1 2 3 5 8 13 ...
Я попытался записать это в газете, и, на мой взгляд, это должно сработать. Мое понимание кода:
Fibo 0 -> = 0
Fibo 1 -> = 1
Fibo 2 -> Fibo 1 + Fibo 0 = 1 + 0 = 1
Fibo 3 -> Fibo 2 + Fibo 1 = 1 + 1 = 2
Fibo 4 -> Fibo 3 + Fibo 2 = 2 + 1 = 3
Fibo 5 -> Fibo 4 + Fibo 3 = 3 + 2 = 5
etc...
Что «делает» код:
Fibo 0 -> = 0
Fibo 1 -> = 1
Fibo 2 -> = 1 + 0 = 1
Fibo 3 -> = 3 (??)
Fibo 4 -> = 5 (this is probably 3+1+1)
Fibo 5 -> = 7 (this is probably once again 5+1+1)
Fibo 6 -> = 9 (once again 7+1+1)
Не могли бы вы помочь мне выяснить, в чем заключается ошибка? Я знаю, что уже было много потоков, похожих на Фибоначчи (и я пытался следовать данному совету), но я не нашел ответа на свою проблему.
С уважением, B





Вот более простой способ воспроизвести вашу проблему:
#!/bin/bash
foo() { echo 42; }
echo $[$foo 1]
Это печатает 1.
Это связано с тем, что $foo не является допустимой переменной (хотя есть функция с таким именем), поэтому она заменяется ничем. echo $[ 1] естественно печатает 1.
Чтобы раскрыть результат функции, используйте $(command substitution):
#!/bin/bash
foo() { echo 42; }
echo $[$(foo 1)]
Это печатает 42. Здесь это применяется к вашему коду:
#!/bin/bash
Fibo() {
case $1 in
0) echo 0;;
1) echo 1;;
*) echo $[$[$(Fibo $[$1-1])]+$[$(Fibo $[$1-2])]] ;;
esac
}
for (( i=0; i<=$1; i++ )); do
Fibo $i
done
Результат:
$ ./foo 10
0
1
1
2
3
5
8
13
21
34
55
@BloodyMary Ваш лучше, поскольку $((..)) - это современный стандартный способ выполнения арифметической оценки оболочки. Я использовал только $[..], потому что ваш исходный пример все время немного съеживался.
Спасибо, что объяснили, как получить результат функции bash. Я не знал, что делаю это неправильно. Я последовал вашему совету, и теперь мой код работает нормально (но он немного отличается от вашего :) - "echo $ (($ [$ (Fibo $ (($ 1-1)))]] + $ [$ (Fibo $ (($ 1 -2)))])) ;; ". Еще раз спасибо!