我基本上是在尝试计算一个素数的BigInteger的因子,我有两个简单的分解函数,它们看起来都应该产生与我在下面使用它们的方式相同的结果,但这不是在这里,有人可以解释发生了什么吗?
let lookupTable = new HashSet<int>(primes)
let isPrime x = lookupTable.Contains x
let factors (n:bigint) =
Seq.filter (fun x -> n % x = 0I) [1I..n]
let factors' (n:bigint) =
Seq.filter (fun x -> n % x = 0I) [1I..bigint(sqrt(float(n)))]
600851475143I
|> fun n -> bigint(sqrt(float(n)))
|> factors
|> Seq.map int
|> Seq.filter isPrime
|> Seq.max // produces 137
600851475143I
|> factors'
|> Seq.map int
|> Seq.filter isPrime
|> Seq.max // produces 6857 (the right answer)
答案 0 :(得分:4)
您的功能不相同。在第一个函数中,候选列表转到n
,过滤函数也使用n
进行余数计算。但是,第二个函数也使用n
进行余数计算,但候选列表却改为sqrt(n)
。
要使第二个函数等效,你需要像下面那样重新构造它:
let factors' (n:bigint) =
let k = bigint(sqrt(float(n)))
Seq.filter (fun x -> k % x = 0I) [1I..k]
更新,稍微澄清一下:
在上面的代码中,注意如何在两个地方使用k
:生成候选的初始列表并计算过滤函数中的余数?这正是我对您的代码所做的更改:我的代码在两个地方使用k
,但您的代码在一个地方使用k
,而在另一个地方使用n
。
这是原始函数在k
中的外观:
let factors' (n:bigint) =
let k = bigint(sqrt(float(n)))
Seq.filter (fun x -> n % x = 0I) [1I..k]
请注意它在一个地方如何使用k
,而在另一个地方使用n
。