我正在他们的官方网站上进行巡回演出,并且我被要求写一个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函数,该函数返回一个返回连续斐波那契数的函数(闭包)。
答案 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
}
}
答案 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())
}
}
但是我想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())
}
}
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())
}
}
答案 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())
}
}