使用F#Async生成Anagram

时间:2017-12-06 09:09:07

标签: string f# anagram f#-async

我试图想办法如何提高程序的速度,其中一个部分是anagram生成。在这种情况下,异步功能是否有帮助,还是有另一种操作字符串的技巧?

let anagramWords = [|"rolex";"viagra";"win";"free";"cash";"grand";"prize";
                     "nude";"porn";"casino";"lottery";"spins";"sex";"gold"; "buy"; "clearance";
                     "business"; "biz"; "money"; "opportunity"; "earn"; "extra"; "potential"; "sleep"; "discount";
                     "bargain"; "credit"; "affordable"; "loans"; "mortages"; "quote"; "dollars"; "invest"; "investment";
                     "bitcoin"; "silver"; "save"; "unsecured"; "pennies"; "million"; "billion";"bureaus";"stock";
                     "bankruptcy"; "eliminate"; "debt"; "billing"; "iphone"; "selling"; "obligation";"trial";
                     "vacation"; "winner";"membership"; "preview"; "sample"; "priority"; "website"; "gift"; "gifts";
                     "present"; "deal"; "fantastic"; "outstanding"; "values"; "act"; "lifetime"; "urgent"|]



let rec distribute e = function
  | [] -> [[e]]
  | x::xs' as xs -> (e::xs)::[for xs in distribute e xs' -> x::xs]

let rec permute = function
  | [] -> [[]]
  | e::xs -> List.collect (distribute e) (permute xs)

let genAnagrams word = 
  word
  |>List.ofSeq 
  |>permute
  |> List.map (fun x -> String(x |> Array.ofList))
  |> Seq.ofList 
  |> Seq.toList

1 个答案:

答案 0 :(得分:1)

使这一点变得更快的一种非常简单的方法是使permute使用数组而不是列表,并使用Array.Parallel.collect代替List.collect。即使从阵列中取下头部效率低下,对于一个10个字符的单词来说,它变得快30%。

open System

let rec distribute e = function
  | [] -> [[e]]
  | x::xs' as xs -> (e::xs)::[for xs in distribute e xs' -> x::xs]

let arrayHeadTail = function [||] -> None | xs -> Some (xs.[0], Array.tail xs)

let rec permute xs =
    match arrayHeadTail xs with
    | None -> [| [] |]
    | Some (e, xs) -> Array.Parallel.collect (distribute e >> List.toArray) (permute xs)

let genAnagrams word = 
  word
  |> Seq.toArray
  |> permute
  |> Array.map String.Concat<char>