Smalltalk斐波那契

sza*_*kel 2 syntax for-loop smalltalk gnu-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.
    ].
Run Code Online (Sandbox Code Playgroud)

Tra*_*ggs 6

如果需要,您可以进一步简化它:

a := b := 1.
(n - 1) timesRepeat: [a := b + (b := a)].
Run Code Online (Sandbox Code Playgroud)

块内的半对称“棘轮”表达式是我一直以来 Smalltalk 的最爱之一。不一定会赢得可读性竞赛,但我认为它看起来很酷。它严格遵循 Smalltalk 从左到右的规则,而在其他语言中,我们希望在放置b在接收者位置。

另请注意我如何替换您的2 to: n do:表达式,因为您没有使用i参数变量。


Uko*_*Uko 5

你为什么不定义一个方法

fib
  ^ self < 2
    ifTrue: [ 1 ]
    ifFalse: [ (self - 2) fib + (self - 1) fib ]
Run Code Online (Sandbox Code Playgroud)

Integer类中并使用它来计算序列?

  1. Smalltalk 不是过程语言,您不应该只用一种方法编写很长的脚本。
  2. 使用递归之美

  • @robmayoff **appl3r** 询问的是实现而不是“优化的实现”。你知道这个简单的规则:1) 让它运行,2) 让它正确,3) 让它快速。我不会争辩说这不是最佳的,但我认为这对于作者理解对象和消息的工作方式很重要。否则我们都可以在 RISC 命令中编程 (4认同)
  • [不幸的是,递归之美导致斐波那契函数的效率极低(指数时间)](http://stackoverflow.com/questions/360748/computational-complexity-of-fibonacci-sequence) 而正确的迭代解决方案在线性时间内运行。 (3认同)

rob*_*off 5

循环主体中有一组额外的括号,这使它在每次循环迭代中创建(但不执行)一个块。这是您要写的内容:

    2 to: n do: [ :i |
        result := (parent + gparent).
        gparent := parent.
        parent := result.
        'come on, do something' displayNl.
    ].
Run Code Online (Sandbox Code Playgroud)