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

Kir*_*lee 20 java lambda functional-programming java-8 java-stream

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

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

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

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

我们怎样才能实现呢?

Hol*_*ger 33

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

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

由于缺少标准对类型,它使用双元素阵列.此外,我使用,.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]));
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • 很明显,该示例正在从流中获取第 91 个元素,因此示例中的 *n* 为 91。 (2认同)

ely*_*yor 5

要获得第N个斐波那契元素(使用减少量):

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

这是怎么回事:

  • Stream.iterate() -产生数字对,每个数字包含2个连续的斐波那契元素。我们必须使用对,因为我们只能通过“ iterate”访问最后一个元素,而不能访问2个或更多先前的元素,因此要生成一个新对,我们将获得最后一对,其中已经包含2个先前的fibonacci元素,并产生下一对。要获得第K个斐波那契元素,我们只需要从第K个对中获得左值即可。

  • .limit(n) -保留前N对,并排除其余对。

  • .reduce((a,b)-> b) -从上一步的N对流中获取最后一对。

  • .get()[0] -从该对中提取斐波那契元素(该对的左值)