3

n番目のフィボナッチ数を返すには Smalltalk を使用する必要があります。この言語は以前に使用したことがありません。このプログラムはどの入力に対しても 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 のお気に入りの 1 つです。必ずしも可読性コンテストに勝つわけではありませんが、見栄えは良いと思います。bこれは、Smalltalk の厳密な左から右へのルールを思い起こさせますが、他の言語では、(元の) 値をレシーバーの位置に配置する前に、右端の割り当てを精神的に評価したいと考えています。

引数変数2 to: n do:を使用していないため、式をどのように置き換えたかにも注意してください。i

于 2014-02-22T17:12:44.697 に答える
5

メソッドを定義しない理由

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

整数クラスでそれを使用してシーケンスを計算しますか?

  1. Smalltalk は手続き型言語ではありません。1 つのメソッドで長いスクリプトを書くべきではありません。
  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 に答える