使用相同代码计算素因子产生不同的结果?

时间:2015-05-31 12:56:35

标签: f# primes biginteger

我基本上是在尝试计算一个素数的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)

1 个答案:

答案 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