首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无限Fibonacci序列在Java 8中的注释

无限Fibonacci序列在Java 8中的注释
EN

Stack Overflow用户
提问于 2014-10-09 22:15:12
回答 1查看 4.6K关注 0票数 5

首先,我是一个JavaScript程序员,对Java8来说还是个新手,并且尝试了新的功能特性。

由于我擅长JS编码,所以我实现了自己的JS惰性函数库,以验证概念。

https://github.com/kenokabe/spacetime

使用这个库,我可以编写无限自然数序列和Fibonacci,如下所示:

JavaScript

代码语言:javascript
复制
var spacetime = require('./spacetime');
var _ = spacetime.lazy(); 

var natural = _(function(n)   //memoized automatically
{
  return n;    // Natural numbers is defined as the `n`th number becomes `n`
});

var natural10 = _(natural)
  .take(10)
  .compute(function(x)
  {
    console.log(x);
  });


//wrap a recursive function to memoize
// must be at the definition in the same scope
var fib = _(function(n)
{
  if (n <= 1)
    return 1; // as the Fib definition in Math
  else
    return fib(n - 2) + fib(n - 1); // as the Fib definition in Math
});

var fib10 = _(fib)
  .take(10)
  .compute(function(x)
  {
    console.log(x);
  });

足够清楚了。重点是,我可以定义自然/斐波纳契无穷序列作为数学定义,然后用延迟求值来计算无限序列所需的部分。

所以,现在我想知道我是否可以用Java8做同样的事情。

关于自然序列,我在这里发布了另一个问题。

Infinite sequence of Natural numbers with Java8 generator

定义自然序列的方法之一是使用iterator of Java8:

Java8

代码语言:javascript
复制
IntStream natural = IntStream.iterate(0, i -> i + 1);

natural
 .limit(10)
 .forEach(System.out::println);

我观察到,IntStream natural = IntStream.iterate(0, i -> i + 1);是一个数学意义上的自然数的公平定义。

但是,我想知道是否有可能像我以前那样定义它,也就是说,

JavaScript

代码语言:javascript
复制
var natural = _(function(n)   //memoized automatically
    {
      return n;    // Natural numbers is defined as the `n`th number becomes `n`
    });

因为这看起来更简洁。不幸的是,答案表明,即使我们使用generate,也可能无法实现。

此外,IntStream.iterate不适合Fibonacci序列。

我寻找generate不确定的斐波纳契序列,我发现最好的结果是

http://blog.informatech.cr/2013/05/08/memoized-fibonacci-numbers-with-java-8/

Java8

代码语言:javascript
复制
private static Map<Integer,Long> memo = new HashMap<>();
static {
   memo.put(0,0L); //fibonacci(0)
   memo.put(1,1L); //fibonacci(1)
}

//And for the inductive step all we have to do is redefine our Fibonacci function as follows:

public static long fibonacci(int x) {
   return memo.computeIfAbsent(x, n -> fibonacci(n-1) + fibonacci(n-2));
}

这不是一个无限序列(Java8中的惰性序列)。

Providing Limit condition on Stream generation

Java8

代码语言:javascript
复制
Stream.generate(new Supplier<Long>() {
    private long n1 = 1;
    private long n2 = 2;

    @Override
    public Long get() {
        long fibonacci = n1;
        long n3 = n2 + n1;
        n1 = n2;
        n2 = n3;
        return fibonacci;
    }
}).limit(50).forEach(System.out::println);

这是一个无穷序列(惰性Stream in Java8),您可以说它被定义为数学。但是,我不喜欢这个实现,因为,正如您所看到的,获得序列有许多内部价值,比如n1 n2 n3然后fibonacci,因此代码结构很复杂,需要控制可变状态--这是反功能的方式--与数学定义不同,这可能不是回忆录。

这是我的问题。有了Java8 Stream,有没有办法用简单的数学方法编写代码来定义斐波纳契的无限序列,比如

JavaScript

代码语言:javascript
复制
 var fib = _(function(n)
    {
      if (n <= 1)
        return 1; // as the Fib definition in Math
      else
        return fib(n - 2) + fib(n - 1); // as the Fib definition in Math
    });

谢谢你的想法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-09 23:39:18

您可以拿出基于地图的回忆录斐波纳契(X),并由此产生无限的流:

代码语言:javascript
复制
LongStream fibs = IntStream.iterate(1, i->i+1).mapToLong(i -> fibonacci(i));

但是,使斐波纳契数无限流的最简单的方法是这样:

代码语言:javascript
复制
LongStream fibs = Stream.iterate(
        new long[]{1, 1},
        f -> new long[]{f[1], f[0] + f[1]}
).mapToLong(f -> f[0]);

正如您所链接的文章所指出的,“无限”实际上意味着“直到长时间溢出”,而这种情况很快就会发生。如果要生成数百个斐波那契数字,请用BigInteger替换long:

代码语言:javascript
复制
    Stream<BigInteger> bigFibs = Stream.iterate(
            new BigInteger[]{BigInteger.ONE, BigInteger.ONE},
            f -> new BigInteger[]{f[1], f[0].add(f[1])}
    ).map(f -> f[0]);
票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26288818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档