2010-11-20 35 views
5

De « Erlang Programmation » par exercice Cesarini 3-2création de la liste en Erlang

Comme je passe par « Erlang programmation » je reçois des questions bizarres de création de liste. De l'exercice 3-2, j'ai écrit deux fonctions similaires.

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 ]. 

alors créez (3) génère comme je m'attendais.

exercice3: créer (3).
[3,2,1]

mais reverse_create ne génère pas la liste attendue.

exercice3: reverse_create (3). Que dois-je changer pour que reverse_create (3) renvoie [1,2,3]?
Merci d'expliquer.

+0

OK, eu l'exemple de travail. Toute idée de pourquoi les deux fonctions similaires ci-dessus renvoient des réponses si différentes? Pourquoi create retourne-t-il une liste propre alors que reverse_create renvoie des listes de listes? – Superpolock

+0

vous pouvez lire ceci pour l'explication: http://learnyousomeerlang.com/starting-out-for-real#lists et regardez également ceci: http://stackoverflow.com/questions/3232786/how-to-concat-lists -en-erlang-sans-créer-imbriqué-listes et http://stackoverflow.com/questions/1919097/functional-programming-what-is-an-improper-list –

Répondre

5

reverse_createreverse_createreverse_create renvoie une liste et vous l'utilise comme élément de tête pour créer la liste qui résulte en des listes imbriquées. Essayez cette solution:

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

EDIT: Une meilleure mise en œuvre serait:

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

Il fait joli O (N^2) de O (N) tâche. –

+0

J'ai fait les modifications comme vous l'avez correctement indiqué puisque ++ copie l'opérande de gauche. –

2

Bien sûr, vous pouvez toujours faire:

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

Cela fait courir plus vite. Mais ce n'est évidemment pas l'intention de l'exercice. :)

3

Normalement, une fonction telle que reverse_create serait exécutée de manière récursive avec un accumulateur.

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

Je lis le même livre, donc je ne suis pas plus expert que vous, mais cela a fonctionné pour moi ...

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

C'est

 


    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.