3

我必须使用 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.
    ].
4

5 回答 5

6

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

a := b := 1.
(n - 1) timesRepeat: [a := b + (b := a)].

块内的半对称“棘轮”表达式是我一直以来 Smalltalk 的最爱之一。不一定会赢得可读性竞赛,但我认为它看起来很酷。它推动了 Smalltalk 严格的从左到右的规则,而在其他语言中,我们希望在将(原始)值放置b在接收器位置之前在心理上评估最右边的分配。

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

于 2014-02-22T17:12:44.697 回答
5

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

    2 to: n do: [ :i |
        result := (parent + gparent).
        gparent := parent.
        parent := result.
        'come on, do something' displayNl.
    ].
于 2014-02-21T22:32:30.537 回答
5

你为什么不定义一个方法

fib
  ^ self < 2
    ifTrue: [ 1 ]
    ifFalse: [ (self - 2) fib + (self - 1) fib ]

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

  1. Smalltalk 不是一种程序语言,您不应该只用一种方法编写一个长脚本。
  2. 使用递归之美
于 2014-02-21T22:05:31.437 回答
1
fib := [:n |
        (n<=1)
            ifTrue: [n]
            ifFalse:
                [
                    (fib value: (n-1)) +
                    (fib value: (n-2))
                ]
    ].
fib value 10

视觉作品

于 2014-10-11T12:11:06.770 回答
0
(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 ].

在法罗。

于 2014-03-05T00:07:40.183 回答