我试图想办法如何提高程序的速度,其中一个部分是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
答案 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>