2010-11-20 31 views
5

Từ "Lập trình Erlang" bằng cách tập thể dục Cesarini 3-2Tạo danh sách trong Erlang

Khi tôi đi qua "Lập trình Erlang" tôi gặp vấn đề về tạo danh sách lạ. Từ bài tập 3-2 tôi đã viết hai hàm tương tự.

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

để tạo (3) tạo như tôi mong đợi.

bài tập3: tạo (3).
[3,2,1]

nhưng reverse_create không tạo danh sách tôi mong đợi.

bài tập3: reverse_create (3).
[[[[] | 1] | 2] | 3]

Tôi cần thay đổi điều gì để reverse_create (3) trả về [1,2,3]? Cảm ơn vì đã giải thích.

+0

OK, đã làm ví dụ. Bất kỳ đầu mối nào tại sao hai hàm tương tự trên lại trả về các câu trả lời khác nhau như vậy? Tại sao tạo lại danh sách trong khi reverse_create trả về danh sách các danh sách? – Superpolock

+0

bạn có thể đọc phần này để được giải thích: http://learnyousomeerlang.com/starting-out-for-real#lists và cũng xem xét những điều sau: http://stackoverflow.com/questions/3232786/how-to-concat-lists -in-erlang-không-tạo-lồng nhau-danh sách và http://stackoverflow.com/questions/1919097/functional-programming-what-is-an-improper-list –

Trả lời

5

reverse_create trả về danh sách và bạn sử dụng phần tử đó làm phần tử đầu để tạo danh sách được tạo thành danh sách lồng nhau. Hãy thử giải pháp này:

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

EDIT: Một thực hiện tốt hơn sẽ là:

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

Nó làm cho tốt đẹp O (N^2) từ O (N) nhiệm vụ. –

+0

Tôi đã thực hiện các chỉnh sửa như bạn đã chỉ ra một cách chính xác vì ++ sao chép toán hạng bên trái. –

2

Tất nhiên, bạn luôn có thể làm:

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

Điều này thực sự sẽ chạy nhanh hơn. Nhưng rõ ràng đó không phải là mục đích của bài tập. :)

3

Thông thường, một hàm như reverse_create sẽ được thực hiện theo kiểu đuôi đệ qui với bộ tích lũy.

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

Tôi đang đọc cuốn sách tương tự, vì vậy tôi không có chuyên môn nhiều hơn bạn, nhưng điều này làm việc cho tôi ...

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

Đây là

 


    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. 

 
Các vấn đề liên quan