Câu trả lời được chấp nhận là tuyệt đẹp và nhanh chóng dễ hiểu nếu bạn đã quen với việc đệ quy cây. Kể từ khi thanh lịch đã được tìm kiếm, mở chủ đề này không hoạt động lâu có vẻ hơi không cần thiết.
Tuy nhiên, giải pháp đơn giản hơn đã được yêu cầu. Các thuật toán lặp lại đôi khi có vẻ đơn giản hơn đối với tôi. Hơn nữa, hiệu suất đã được đề cập như một chỉ số về chất lượng, và các quá trình lặp lại đôi khi nhanh hơn các đệ quy.
Đoạn mã sau là đệ quy đuôi và tạo ra một quá trình lặp lại. Nó đòi hỏi một phần ba thời gian để tính toán các kết hợp của kích thước 12 từ một danh sách 24 yếu tố.
let combinations size aList =
let rec pairHeadAndTail acc bList =
match bList with
| [] -> acc
| x::xs -> pairHeadAndTail (List.Cons ((x,xs),acc)) xs
let remainderAfter = aList |> pairHeadAndTail [] |> Map.ofList
let rec comboIter n acc =
match n with
| 0 -> acc
| _ ->
acc
|> List.fold (fun acc alreadyChosenElems ->
match alreadyChosenElems with
| [] -> aList //Nothing chosen yet, therefore everything remains.
| lastChoice::_ -> remainderAfter.[lastChoice]
|> List.fold (fun acc elem ->
List.Cons (List.Cons (elem,alreadyChosenElems),acc)
) acc
) []
|> comboIter (n-1)
comboIter size [[]]
Ý tưởng cho phép quy trình lặp lại là tính toán trước một bản đồ của phần tử đã chọn cuối cùng vào danh sách các phần tử còn lại còn lại. Bản đồ này được lưu trữ trong remainderAfter
.
Mã không súc tích, cũng không phù hợp với đồng hồ trữ tình và vần điệu.
Nguồn
2016-06-01 17:51:08
Câu hỏi liên quan đến mơ hồ: http://stackoverflow.com/questions/286427/calculating-permutations-in-f – Benjol