用于解决fibonacci的Java 8 Lambda表达式(非递归方式)

我是Java 8中使用Lambda表达式function的初学者.Lambda表达式在解决Prime数字检查,阶乘等程序方面非常有用。

然而,它们可以有效地用于解决像Fibonacci这样的问题,其中当前值取决于前两个值的总和。 我已经很好地使用Lambda表达式有效地解决了素数检查问题。 下面给出了相同的代码。

boolean checkPrime=n>1 && LongStream.range(2, (long) Math.sqrt(n)).parallel().noneMatch(e->(n)%e==0); 

在上面的noneMatch方法代码中,我们使用范围中的当前值( e )进行评估。 但对于Fibonacci问题,我们需要前两个值。

我们怎样才能实现呢?

最简单的解决方案是使用Pair的流:

 Stream.iterate(new long[]{ 1, 1 }, p->new long[]{ p[1], p[0]+p[1] }) .limit(92).forEach(p->System.out.println(p[0])); 

由于缺少标准对类型,它使用双元素arrays。 此外,我使用.limit(92)因为我们无法使用long值评估更多元素。 但是很容易适应BigInteger

 Stream.iterate(new BigInteger[]{ BigInteger.ONE, BigInteger.ONE }, p->new BigInteger[]{ p[1], p[0].add(p[1]) }) .forEach(p->System.out.println(p[0])); 

这将一直运行,直到你没有足够的内存来表示下一个值。

顺便说一句,从流中获取第n个元素:

 Stream.iterate(new long[]{1, 1}, p -> new long[]{p[1], p[0] + p[1]}) .limit(91).skip(90).findFirst().get()[1]; 

解决斐波那契(非递归方式)

你的方法不会发生这种情况

基于前两个数字生成Fibonacci数是基于前两个数字 ,即它是递归算法,即使您在没有递归但是在循环中实现它。

还有其他基于矩阵指数的方法,因此您可以计算第n个斐波那契数而不计算n-1之前的数字,但对于您的问题(计算系列),这没有意义。

那么,最后回答你的问题,即如何在之前的两个元素上使用Lambda表达式? :有一个元组列表,每个元组包含两个连续的数字,并迭代它,每一步添加一个新的元组。

获得Nth fibonacci元素(使用减少):

 Stream.iterate(new long[] {1, 1}, f -> new long[] {f[1], f[0] + f[1]}) .limit(n) .reduce((a, b) -> b) .get()[0]; 

如果您想要一个非递归实现来查找第n个Fibonacci序列,您可以使用以下公式:

 Un = ( (1+sqrt(5))^n - (1-sqrt(5))^n ) / (2^n * sqrt(5)) 

比奈的斐波纳契数公式

 long fibonacci(int n) { return (long) ((Math.pow(1 + Math.sqrt(5), n) - Math.pow(1 - Math.sqrt(5), n)) / (Math.pow(2, n) * Math.sqrt(5))); }