Combinations and Permutations in F#

后端 未结 3 948
北荒
北荒 2020-12-13 11:23

I\'ve recently written the following combinations and permutations functions for an F# project, but I\'m quite aware they\'re far from optimised.

/// Rotates         


        
3条回答
  •  爱一瞬间的悲伤
    2020-12-13 11:47

    If you want to write efficient functional code, then it is a good idea to avoid using the @ operator, because concatentation of lists is very inefficient.

    Here is an example of how you can write a function to generate all combinations:

    let rec combinations acc size set = seq {
      match size, set with 
      | n, x::xs -> 
          if n > 0 then yield! combinations (x::acc) (n - 1) xs
          if n >= 0 then yield! combinations acc n xs 
      | 0, [] -> yield acc 
      | _, [] -> () }
    
    combinations [] 3 [1 .. 4]
    

    The parameters of the function are:

    • acc is used to remember elements that are already selected to be included in the combination (initially this is an empty list)
    • size is the remaining number of elements that we need to add to acc (initially this is the required size of the combinations)
    • set is the set elements to choose from

    The function is implemented using a simple recursion. If we need to generate combinations of size n then we can either add or don't add the current element, so we try to generate combinations using both options (first case) and add all of them to the generated sequence using yield!. If we need 0 more elements, then we successfuly generated a combination (second case) and if we end with some other number but don't have any remaining elements to use then we cannot return anything (last case).

    Combinations with repetition would be similar - the difference is that you don't need to remove the elements from the list (by using just xs in the recursive calls) so there are more options of what to do.

提交回复
热议问题