【发布时间】:2012-01-17 23:35:06
【问题描述】:
我有一系列素数除数,我想为每个素数候选者迭代。我使用 GetEnumerator() MoveNext() 和 Current。我无法重新初始化枚举器以从头开始。我尝试了 Reset(),它已编译,但运行时错误未实现。
我正在使用 F# 2.0 Interactive build 4.0.40219.1
有什么建议吗?
问候, 道格
为了澄清问题:对于每个素数候选者 N,我想遍历素数除数序列(最多约 sqrt N)并完全分解 N 或确定它是否为素数。使用 GetEnumerator、MoveNext、Current 方法适用于第一个主要候选人,但在第二个主要候选人上,我想从头开始迭代我的除数序列。看来,这样做的唯一方法是创建一个新的迭代器(这对于大量素数候选者来说很尴尬)或创建一个新的素数序列(我不想这样做)。
使用“seqPrimes 中的除数”之类的建议似乎在停止之前用尽了所有除数,但我想在素数除数除以主要候选人时立即停止。
如果上述陈述中我的逻辑有错误,请告诉我。
我调查了 Seq.cache,这对我有用。结果代码如下:
// Recursive isprime function (modified from MSDN)
let isPrime n =
let rec check i =
i > n/2 || (n % i <> 0 && check (i + 2))
if n = 2 then true
elif (n%2) = 0 then false
else check 3
let seqPrimes = seq { for n in 2 .. 100000 do if isPrime n then yield n }
// Cache the sequence to avoid recomputing the sequence elements.
let cachedSeq = Seq.cache seqPrimes
// find the divisors of n (or determine prime) using the seqEnum enumerator
let rec testPrime n (seqEnum:System.Collections.Generic.IEnumerator<int>) =
if n = 1 then printfn "completely factored"
else
let nref = ref n
if seqEnum.MoveNext() then
let divisor = seqEnum.Current
//printfn "trial divisor %A" divisor
if divisor*divisor > n then printfn "prime %A" !nref
else
while ((!nref % divisor) = 0) do
printfn "divisor %A" divisor
nref := !nref / divisor
testPrime !nref seqEnum
// test
for x = 1000000 to 1000010 do
printfn "\ndivisors of %d = " x
let seqEnum = cachedSeq.GetEnumerator()
testPrime x seqEnum
seqEnum.Dispose() // not needed
【问题讨论】:
-
当您可以只使用
for x in y语法时,我会发现实际上需要在IEnumerator上显式调用成员是非常罕见的。如果你需要;只需创建一个新的枚举器。发布您的代码会很有帮助,因为我认为我们可以找到更好的替代方案。 -
你能举一个具体的例子来说明这个错误吗?
-
你试过使用 Seq.cache 吗?
标签: f# ienumerable