У меня есть последовательность делителей простых чисел, которую я хочу перебрать для каждого основного кандидата. Я использую GetEnumerator() MoveNext() и Current. Я не могу повторно инициализировать счетчик, чтобы начать с самого начала. Я попытался скомпилировать Reset(), который скомпилировал, но дает ошибку выполнения, которая не реализована.F #: хотите повторно инициализировать перечислитель
Я использую F # 2.0 Интерактивное построить 4.0.40219.1
Любые предложения?
С уважением, Doug
Для выяснения вопроса: Для каждого простого кандидата NI хочет итерацию через премьер последовательность делителей (до приблизительно квадратного корня N) и полностью фактор N или определить, является ли премьер , Используя GetEnumerator, MoveNext, Текущий подход работает для первого основного кандидата, но на втором премьер-кандидате я хочу итерации по моей последовательности делителей с самого начала. Похоже, что единственный способ сделать это - создать новый итератор (что неудобно для большого числа простых кандидатов) или создать новую премьер-последовательность (которую я не хочу делать).
Попытка использовать что-то вроде «делителей в 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
Мне бы очень редко приходилось явно обращаться к членам на «IEnumerator», когда вы могли просто использовать синтаксис 'for x in y'. Если вам нужно; просто создайте новый счетчик. Проводка кода будет полезна, потому что я думаю, что мы можем найти лучшую альтернативу. – vcsjones
Можете ли вы привести конкретный пример, демонстрирующий ошибку? – pad
Вы пытались использовать Seq.cache? – Huusom