最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Infinite Fibonacci Sequence with Memoized in Java 8 - Stack Overflow

programmeradmin3浏览0评论

Firstly, I'm a JavaScript programmer, and fairly new to Java8 and trying the new functional feature.

Since I expertise JS coding, I implemented my own JS lazy-functional library for proof of concept.

Using the library, I could write Infinite sequence of Natural numbers and Fibonacci as below:

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 bees `n`
});

var natural10 = _(natural)
  .take(10)
  pute(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)
  pute(function(x)
  {
    console.log(x);
  });

Clear enough. The point is that I can define Natural/Fibonacci infinite sequence as the math definition as it is, then later pute the required part of the infinite sequence with lazy-evaluation.

So, now I wonder if I can do the same manner with Java8.

For natural sequence, I had post another Question here.

Infinite sequence of Natural numbers with Java8 generator

One of the way to define Natural sequence is to use iterator of Java8:

Java8

IntStream natural = IntStream.iterate(0, i -> i + 1);

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

I observe IntStream natural = IntStream.iterate(0, i -> i + 1); is a fair definition of natural numbers in math sense.

However, I wonder if it's possible to define it as I did before, that is,

JavaScript

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

because this looks more concise. Unfortunately, the answers suggest it's probably not possible even we use generate.

In addition, IntStream.iterate does not fit for Fibonacci sequence.

I seek web to generate indefinite sequence of Fibonacci, the best results I found are

/

Java8

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 memoputeIfAbsent(x, n -> fibonacci(n-1) + fibonacci(n-2));
}

This is not an infinite sequence (lazy Stream in Java8).

and

Providing Limit condition on Stream generation

Java8

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);

This is an infinite sequence (lazy Stream in Java8), and you could say it's defined as Math. However I do not like this implementation because, as you can see, there are many internal valuable to obtain the sequence such as n1 n2 n3 then fibonacci, accordingly the code structure is plicated and you need to control mutable state which is anti-functional manner - unlike the math definition, and probably this is not memoized.

So, here's my question. With Java8 Stream, is there any way to write a code to define the infinite sequence of fibonacci in concise math manner with memoization like

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
    });

Thanks for your thought.

Firstly, I'm a JavaScript programmer, and fairly new to Java8 and trying the new functional feature.

Since I expertise JS coding, I implemented my own JS lazy-functional library for proof of concept.

https://github./kenokabe/spacetime

Using the library, I could write Infinite sequence of Natural numbers and Fibonacci as below:

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 bees `n`
});

var natural10 = _(natural)
  .take(10)
  .pute(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)
  .pute(function(x)
  {
    console.log(x);
  });

Clear enough. The point is that I can define Natural/Fibonacci infinite sequence as the math definition as it is, then later pute the required part of the infinite sequence with lazy-evaluation.

So, now I wonder if I can do the same manner with Java8.

For natural sequence, I had post another Question here.

Infinite sequence of Natural numbers with Java8 generator

One of the way to define Natural sequence is to use iterator of Java8:

Java8

IntStream natural = IntStream.iterate(0, i -> i + 1);

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

I observe IntStream natural = IntStream.iterate(0, i -> i + 1); is a fair definition of natural numbers in math sense.

However, I wonder if it's possible to define it as I did before, that is,

JavaScript

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

because this looks more concise. Unfortunately, the answers suggest it's probably not possible even we use generate.

In addition, IntStream.iterate does not fit for Fibonacci sequence.

I seek web to generate indefinite sequence of Fibonacci, the best results I found are

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

Java8

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.puteIfAbsent(x, n -> fibonacci(n-1) + fibonacci(n-2));
}

This is not an infinite sequence (lazy Stream in Java8).

and

Providing Limit condition on Stream generation

Java8

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);

This is an infinite sequence (lazy Stream in Java8), and you could say it's defined as Math. However I do not like this implementation because, as you can see, there are many internal valuable to obtain the sequence such as n1 n2 n3 then fibonacci, accordingly the code structure is plicated and you need to control mutable state which is anti-functional manner - unlike the math definition, and probably this is not memoized.

So, here's my question. With Java8 Stream, is there any way to write a code to define the infinite sequence of fibonacci in concise math manner with memoization like

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
    });

Thanks for your thought.

Share Improve this question edited May 23, 2017 at 10:31 CommunityBot 11 silver badge asked Oct 9, 2014 at 22:15 user1028880user1028880 1
  • This other article Java Infinite Streams provides a conceptual explanation of streams and the last example demonstrates an infinite stream of fibonacci numbers, although it does not use Java 8 streams. – Edwin Dalorzo Commented Dec 18, 2014 at 18:22
Add a ment  | 

1 Answer 1

Reset to default 16

You can take your map-based memoized fibonacci(x) and make an infinite stream out of it like this:

LongStream fibs = IntStream.iterate(1, i->i+1).mapToLong(i -> fibonacci(i));

But the easiest way to make an infinite stream of fibonacci numbers is like this:

LongStream fibs = Stream.iterate(
        new long[]{1, 1},
        f -> new long[]{f[1], f[0] + f[1]}
).mapToLong(f -> f[0]);

As the article you linked to points out, "infinite" really means "until long overflows" which happens quickly. If you want to generate hundreds of fibonacci numbers, replace long with BigInteger:

    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]);
发布评论

评论列表(0)

  1. 暂无评论