我正在努力学习F# 我写了一个函数来计算素数。
let PrimeFactors x =
let rec PrimeFactorsRecursive x div list =
if x % div = 0 then PrimeFactorsRecursive (x/div) div list @ [div]
elif div > int(System.Math.Sqrt(float(x))) then
if x > 1 then list @ [x]
else list
else PrimeFactorsRecursive x (div + 1) list
PrimeFactorsRecursive x 2 []
现在我不确定这是一个好的F#函数还是更像是“c#,用f#编写”。
是否有一种“更多”功能的方式来编写此代码?
答案 0 :(得分:3)
代码中的原始问题是您使用@
来连接两个列表。将两个列表相关联需要线性时间,而不是恒定时间。
常量方法是使用::
运算符将新素数添加到列表的开头,如下所示:
let primeFactors x =
let rec fact x div list =
if x % div = 0 then
fact (x/div) div (div::list)
elif div > int(sqrt (float x)) then
if x > 1 then x::list
else list
else
fact x (div+1) list
fact x 2 []
同样let
绑定值通常遵循camleStyle命名转换。
答案 1 :(得分:1)
尚未提及的另一个“改进”是使用管道,而不是
int(System.Math.Sqrt(float(x)))
你有
(x |> float |> sqrt |> int)
答案 2 :(得分:0)
您可以使用受保护的模式来减少if-expression嵌套。除此之外,它对我来说看起来是完全合理的惯用功能代码。