2014-10-09 10 views
5

In primo luogo, sono un programmatore JavaScript e abbastanza nuovo per Java8 e sto provando la nuova funzionalità.Sequenza infinita di Fibonacci con Memoized in Java 8

Dal momento che conosco la codifica JS, ho implementato la mia libreria lazy-funzionale JS per la dimostrazione del concetto.

https://github.com/kenokabe/spacetime

Utilizzando la libreria, ho potuto scrivere sequenza infinita di numeri naturali e Fibonacci come di seguito:

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

chiaro abbastanza. Il punto è che posso definire la sequenza infinita Natural/Fibonacci come la definizione matematica così com'è, quindi calcolare la parte richiesta della sequenza infinita con la valutazione pigra.

Quindi, ora mi chiedo se posso fare la stessa cosa con Java8.

Per una sequenza naturale, ho inviato qui un'altra domanda.

Infinite sequence of Natural numbers with Java8 generator

Uno dei modi per definire la sequenza naturale è quello di utilizzare iterator di Java8:

Java8

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

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

osservo IntStream natural = IntStream.iterate(0, i -> i + 1); è una giusta definizione dei numeri naturali in matematica senso.

Tuttavia, mi chiedo se è possibile definirla come ho fatto prima, cioè,

JavaScript

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

perché questo sembra più concisa. Sfortunatamente, le risposte suggeriscono che probabilmente non è possibile nemmeno usiamo generate.

Inoltre, IntStream.iterate non si adatta alla sequenza di Fibonacci.

cerco Web per generate sequenza indefinita di Fibonacci, i migliori risultati che ho trovato sono

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

Questa non è una sequenza infinita (pigro Stream in Java8).

e

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

Si tratta di una sequenza infinita (pigro Stream in Java8), e si potrebbe dire che è definita come la matematica. Tuttavia non mi piace questa implementazione, perché, come si può vedere, ci sono molti interno preziosi per ottenere la sequenza come n1n2n3 poi fibonacci, di conseguenza la struttura del codice è complicato e è necessario controllare lo stato mutabile che è anti- funzionale modo - a differenza della definizione matematica, e probabilmente questo non è memoized.

Quindi, ecco la mia domanda. Con Java8 Stream, c'è qualche modo per scrivere un codice per definire la sequenza infinita di Fibonacci in modo conciso matematica con Memoizzazione come

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

Grazie per il vostro pensiero.

+0

questo altro articolo [Java Infinite Streams] (http://www.ticocoding.com/java-infinite-streams/) fornisce una concettuale spiegazione dei flussi e l'ultimo esempio dimostra un flusso infinito di numeri di Fibonacci, sebbene non utilizzi stream Java 8. –

risposta

16

Si può prendere la Fibonacci memoized map-based (x) ed effettuare un flusso infinito fuori di esso in questo modo:

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

Ma il modo più semplice per fare un flusso infinito di numeri di Fibonacci è come questo:

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

Come l'articolo si è collegato al sottolinea, "infinito" significa in realtà "solo molto tempo overflow", che avviene rapidamente. Se si desidera generare centinaia di numeri di Fibonacci, sostituire a lungo con 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

Great.Anche se la presentazione di stile della funzione in Java8 mi confonde ancora, potrei piuttosto confermare che corrisponde alla definizione matematica. Forse avrei posto un'altra domanda. Che cosa è 'map' o' mapToLong' (f -> f [0]), so cosa sia 'map', ma non potrei seguire il ruolo logico qui. Anche la 'mappa' ha funzionalità di memorizzazione automatica? –

+0

Ho pubblicato un altro Q per questo problema: http://stackoverflow.com/questions/26290716/map-based-memoized-in-java8 –

+0

È possibile studiare [questa domanda correlata e le sue risposte] (http: // stackoverflow .com/q/25880331/2711488) ... – Holger

Problemi correlati