2010-11-20 28 views
5

Da "Erlang Programmazione" di Cesarini esercizio 3-2creazione List in Erlang

come vado attraverso "Erlang Programmazione" ottengo problemi creazione della lista strani. Dall'esercizio 3-2 ho scritto due funzioni simili.

create(0) -> []; 
create(N) when N > 0 -> [ N | create(N-1) ]. 

reverse_create(0) -> []; 
reverse_create(N) when N > 0 -> [ reverse_create(N-1) | N ]. 

così creare (3) genera come mi aspetterei.

esercizio3: creare (3).
[3,2,1]

ma reverse_create non genera la lista che mi aspetto.

esercizio3: reverse_create (3).
[[[[] | 1] | 2] | 3]

Cosa devo cambiare in modo che reverse_create (3) restituisca [1,2,3]? Grazie per aver spiegato.

+0

OK, ha funzionato l'esempio Qualche indizio sul perché le due funzioni simili sopra riportino risposte così diverse? Perché creare restituire una lista pulita mentre reverse_create restituisce elenchi di elenchi? – Superpolock

+0

puoi leggere questo per spiegazioni: http://learnyousomeerlang.com/starting-out-for-real#lists e guarda anche questi: http://stackoverflow.com/questions/3232786/how-to-concat-lists -in-erlang-without-creating-nested-lists e http://stackoverflow.com/questions/1919097/functional-programming-what-is-an-improper-list –

risposta

5

reverse_create restituisce un elenco e lo si utilizza come elemento principale per creare l'elenco che risulta in elenchi annidati. Prova questa soluzione:

reverse_create(0) -> []; 
reverse_create(N) when N > 0 -> reverse_create(N-1) ++ [N]. 

EDIT: una migliore implementazione sarebbe:

reverse_create2(N) -> reverse_create_helper(N, []). 

reverse_create_helper(0, Acc) -> 
    Acc; 
reverse_create_helper(N, Acc) -> 
    reverse_create_helper(N-1, [N|Acc]). 
+1

Fa bella O (N^2) da O (N) compito. –

+0

Ho apportato le modifiche come hai sottolineato correttamente poiché ++ copia l'operando di sinistra. –

2

Naturalmente, si può sempre fare:

reverse_create(N) -> lists:reverse(create(N)). 

Questo sarebbe in realtà correre più veloce. Ma ovviamente non è l'intenzione dell'esercizio. :)

3

Normalmente una funzione come reverse_create sarebbe eseguita in modo ricorsivo in coda con un accumulatore.

reverse_create(N) -> 
    reverse_create(N, []). 

reverse_create(0, Acc) -> 
    Acc; 
reverse_create(N, Acc) when N > 0 -> 
    reverse_create(N - 1, [N | Acc]). 
1

sto leggendo lo stesso libro, quindi sono più esperto di te, ma questo ha funzionato per me ...

create(0) -> []; 
create(N) when N > 0 -> create(N-1) ++ [N]. 

reverse_create(0) -> []; 
reverse_create(N) when N > 0 -> [N|create(N-1)]. 
-1

Questo è

 


    reverse_create(0) -> []; 
    reverse_create(N) -> 
     list_create_1(1, N, []). 

    list_create_1(I, N, List) when N >= I -> 
     list_create_1(I + 1, N, [I | List]); 
    list_create_1(_, _, List) -> List.