斐波纳契封闭了

时间:2014-08-25 17:37:59

标签: go closures fibonacci

我正在他们的官方网站上进行巡回演出,并且我被要求写一个Fibonacci发电机。这是:

 package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    first := 0
    second := 0
    return func() int{
        if(first == 0) {
         first = 1
         second = 1
         return 0
        }else {
            current := first   
            firstc := second
            second = first + second
            first = firstc
            return current
        }



    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

有效。但是我觉得它非常难看,我确信必须有更好的解决方案。我一直在考虑在代码审查中发布这个,但是因为我要求更好的方法,我认为这是发布它的正确位置。

有没有更好的方法来编写此代码?

这是任务:

  

实现一个fibonacci函数,该函数返回一个返回连续斐波那契数的函数(闭包)。

10 个答案:

答案 0 :(得分:32)

我最喜欢的实现迭代斐波纳契数的干净方法是使用first作为f i - 1 second作为f i 。 Fibonacci方程表明:

f i + 1 = f i + f i - 1

除非我们在代码中写这个,否则在下一轮中我们会增加i。所以我们有效地做了:

f next i = f current i + f current i - 1

f next i - 1 = f current i - 1

我喜欢在代码中实现它的方式是:

first, second = second, first + second

first = second部分对应于更新f next i - 1 = f current i - 1 second = first + second部分对应于更新f next i = f current i + f current i - 1

然后我们要做的就是返回第一个旧值,因此在进行更新之前,我们会将它存储在临时变量中。总的来说,我们得到:

// fibonacci returns a function that returns
// successive fibonacci numbers from each
// successive call
func fibonacci() func() int {
    first, second := 0, 1
    return func() int {
        ret := first
        first, second = second, first+second
        return ret
    }
}

Go Playground上看到它。

答案 1 :(得分:4)

我会使用多个赋值,减少标识符的长度,并删除if if statment:

func fibonacci() func() int {
    var a, b int
    b = 1
    return func() int {
        ret := a
        a, b = b, a+b
        return ret
    }
}

答案 2 :(得分:3)

一个小把戏

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    a := 0
    b := 1
    return func() int {
        a, b = b, a+b
        return b-a
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

答案 3 :(得分:2)

另一种方法

func fibonacci() func() int {
    n1, n := -1, 1
    return func() int {
        n1, n = n, n1+n
        return n
    }
}

The Go Playground

答案 4 :(得分:1)

这也是我的建议,将每个数字存储在地图中。

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
// 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610,
// 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025,
// 121393, 196418, 317811, 514229
func fibonacci() func() int {
    numbers := make(map[int]int)
    n := 0
    return func() int {
        if n == 0 {
            numbers[n] = 0
            n++
            return 0
        }
        if n == 1 {
            numbers[n] = 1
            n++
            return 1
        }
        number := numbers[n-1] + numbers[n-2]
        numbers[n] = number
        n++
        return number
    }}

func main() {
    f := fibonacci()
    for i := 0; i < 30; i++ {
        fmt.Println(f())
    }
}

答案 5 :(得分:0)

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    a, b, sum := 1, 1, 0
    return func() int {
        a,b = b,sum
        sum = a + b
        return b
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

答案 6 :(得分:0)

除了已经提供的答案外,您还可以使用延迟功能:

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    secondLast := 0
    last := 1
    return func() int {
        defer func() {
            secondLast, last = last, secondLast+last
        }()
        return secondLast
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

Go Playground

但是我想jwoodalls的答案是表现最好的。

编辑:但是,如果您想使用无符号整数(以展示您可以在体系结构上计算出多少斐波那契数;)),则必须使用带有保留返回值的变量或defer函数的方法。 / p>

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an uint.
func fibonacci() func() uint {
    var secondLast uint
    var last uint = 1
    return func() uint {
        defer func() {
            secondLast, last = last, secondLast + last
        }()
        return secondLast
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

Go Playground

EditEdit:或者甚至更好:使用float64!

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an float64.
func fibonacci() func() float64 {
    var secondLast float64
    var last float64 = 1
    return func() float64 {
        defer func() {
            secondLast, last = last, secondLast+last
        }()
        return secondLast
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}

Go Playground

答案 7 :(得分:0)

或者您可以使用此方法...简单且易于理解,尽管与以前的答案没有很大不同。

PeriodIndex

答案 8 :(得分:0)

我就是这样做的。

func fibonacci() func() int {
     var s = []int{0,1}

     return func() int{
                ret := s[0]
                s[0],s[1] = s[1],s[0]+s[1]
                return ret
            }
}

答案 9 :(得分:-1)

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    first:=0
    second:=0
    return func() int{
        if second == 0 {
            second = 1
        } else if first == 0 {
            first = 1
        } else {
            first, second = second, first + second
        }
        return second
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}