Smalltalk Фибоначчи
Я должен использовать Smalltalk, чтобы вернуть n-е число Фибоначчи, я раньше не использовал этот язык. Эта программа возвращает 1 для любого ввода, и я не знаю почему. Я даже не повторял цикл for. Может ли кто-нибудь помочь мне? Благодарю.
'Which fibonacci number do you want? (n>2)' printNl.
n := stdin nextLine asInteger.
(n <= 2)
ifTrue: ['Type a larger number, F(1) and F(2) equals 1!' displayNl.]
ifFalse: [
result:= 1.
parent := 1.
gparent := 1.
2 to: n do: [ :i | [
result := (parent + gparent).
gparent := parent.
parent := result.
'come on, do something' displayNl.
]
].
result displayNl.
].
5 ответов
У вас есть дополнительный набор скобок в теле цикла, что позволяет создавать (но не выполнять) блок на каждой итерации цикла. Вот что вы хотели написать:
2 to: n do: [ :i |
result := (parent + gparent).
gparent := parent.
parent := result.
'come on, do something' displayNl.
].
Вы можете упростить это еще больше, если хотите:
a := b := 1.
(n - 1) timesRepeat: [a := b + (b := a)].
Полусимметричное "храповое" выражение внутри блока - одно из моих любимых писем в Smalltalk. Не обязательно выигрывать конкурсы по читабельности, но я думаю, что это круто. Это приводит к строгому соблюдению правил Smalltalk слева направо, в то время как в других языках мы хотели бы мысленно оценить самое правое назначение, прежде чем помещать (оригинальное) значение b
в положении приемника.
Обратите внимание, как я заменил ваш 2 to: n do:
выражение, так как вы не используете i
переменная аргумента.
Почему бы вам не определить метод
fib
^ self < 2
ifTrue: [ 1 ]
ifFalse: [ (self - 2) fib + (self - 1) fib ]
в классе Integer и использовать его для расчета последовательности?
- Smalltalk не является процедурным языком, вы не должны писать только длинный скрипт в одном методе.
- Используйте красоту рекурсии
fib := [:n |
(n<=1)
ifTrue: [n]
ifFalse:
[
(fib value: (n-1)) +
(fib value: (n-2))
]
].
fib value 10
для VisualWorks
(1 to: n)
inject: OrderedCollection new
into: [ :coll :each |
| p pp n |
p := coll at: (each - 1) ifAbsent: [ 0 ].
pp := coll at: (each - 2) ifAbsent: [ 0 ].
n := p + pp.
((n = 0) and: [ each = 1 ])
ifTrue: [ n := 1 ].
coll
add: n;
yourself ].
В фаро.