Một phần của chương trình của tôi yêu cầu tôi có thể trộn ngẫu nhiên các phần tử danh sách. Tôi cần một chức năng như vậy khi tôi đưa cho nó một danh sách, nó sẽ giả ngẫu nhiên sắp xếp lại các phần tử trong danh sách.
Thay đổi sắp xếp Phải hiển thị trong mỗi cuộc gọi có cùng danh sách.
Triển khai của tôi dường như hoạt động tốt nhưng tôi cảm thấy rằng nó khá dài và đang tăng cơ sở mã của tôi và cũng có thể, tôi có cảm giác rằng đó không phải là giải pháp tốt nhất để làm điều này. Vì vậy, tôi cần thực hiện ngắn hơn nhiều. Dưới đây là thực hiện của tôi:Các yếu tố xáo trộn trong danh sách (sắp xếp lại các yếu tố danh sách ngẫu nhiên)
-module(shuffle). -export([list/1]). -define(RAND(X),random:uniform(X)). -define(TUPLE(Y,Z,E),erlang:make_tuple(Y,Z,E)). list(L)-> Len = length(L), Nums = lists:seq(1,Len), tuple_to_list(?TUPLE(Len,[],shuffle(Nums,L,[]))). shuffle([],_,Buffer)-> Buffer; shuffle(Nums,[Head|Items],Buffer)-> {Pos,NewNums} = pick_position(Nums), shuffle(NewNums,Items,[{Pos,Head}|Buffer]). pick_position([N])-> {N,[]}; pick_position(Nos)-> T = lists:max(Nos), pick(Nos,T). pick(From,Max)-> random:seed(begin (case random:seed(now()) of undefined -> NN = element(3,now()), {?RAND(NN),?RAND(NN),?RAND(NN)}; Any -> Any end) end ), T2 = random:uniform(Max), case lists:member(T2,From) of false -> pick(From,Max); true -> {T2,From -- [T2]} end.
On chạy nó trong vỏ:
F:\> erl Eshell V5.8.4 (abort with ^G) 1> c(shuffle). {ok,shuffle} 2> shuffle:list([a,b,c,d,e]). [c,b,a,e,d] 3> shuffle:list([a,b,c,d,e]). [e,c,b,d,a] 4> shuffle:list([a,b,c,d,e]). [a,b,c,e,d] 5> shuffle:list([a,b,c,d,e]). [b,c,a,d,e] 6> shuffle:list([a,b,c,d,e]). [c,e,d,b,a]Tôi thúc đẩy bởi một thực tế rằng trong stdlib không có chức năng như vậy. Một nơi nào đó trong trò chơi của tôi, tôi cần phải xáo trộn mọi thứ và tôi cũng cần phải tìm ra giải pháp hiệu quả nhất cho vấn đề, không chỉ là giải pháp hiệu quả.
Một số người có thể giúp xây dựng một phiên bản ngắn hơn của giải pháp không? có lẽ còn hiệu quả hơn? Cảm ơn bạn
Cảm ơn @Adam giải pháp tuyệt vời. Tôi yêu nó –
hi. Tôi có thể thêm rằng bạn nên hạt giống trước khi sử dụng 'ngẫu nhiên: thống nhất'? nếu không bạn sẽ nhận được kết quả tương tự trong các lần thực hiện khác nhau của VM và trong nhiều ứng dụng, điều này là không mong muốn. – user601836
@ user601836 Điểm tốt! Lưu ý rằng bạn chỉ cần thực hiện điều này một lần cho mỗi quá trình và không phải cho mỗi lần chạy 'shuffle: list/1'. –