车轮分解的Eratosthenes筛 [英] Sieve of Eratosthenes with Wheel Factorization

查看:152
本文介绍了车轮分解的Eratosthenes筛的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实施一个相当快的素数生成器,我获得了一些不错的结果与几个优化在eratosthenes筛。特别地,在算法的初始部分,我以这种方式跳过2和3的所有倍数:

i'm implementing a reasonably fast prime number generator and i obtained some nice results with a few optimizations on the sieve of eratosthenes. In particular, during the preliminary part of the algorithm, i skip all multiples of 2 and 3 in this way:

template<class Sieve, class SizeT>
void PrimeGenerator<Sieve, SizeT>::factorize()
{
    SizeT c = 2;
    m_sieve[2] = 1;
    m_sieve[3] = 1;

    for (SizeT i=5; i<m_size; i += c, c = 6 - c)
        m_sieve[i] = 1;
}

这里m_sieve是一个根据eratosthenes的筛子的布尔数组。
我认为这是一种Wheel factorization只考虑primes 2和3,增加遵循模式2,4,2,4,..我想做的是实现一个更大的车轮,也许考虑素数2,3和5.
我已经读了很多关于它的文档,但我没有看到任何实现与筛选的eratosthenes ...一个示例代码可以帮助很多,但也有一些提示好的:)
谢谢。

Here m_sieve is a boolean array according to the sieve of eratosthenes. I think this is a sort of Wheel factorization only considering primes 2 and 3, incrementing following the pattern 2, 4, 2, 4,.. What i would like to do is to implement a greater wheel, maybe considering primes 2,3 and 5. I already read a lot of documentation about it, but I didn't see any implementation with the sieve of eratosthenes... a sample code could help a lot, but also some hints would be nice :) Thanks.

推荐答案

这是我几年前写的一些OCaml代码:

You can go even further. Here is some OCaml code I wrote a few years ago:

let eratosthene borne =
  let remove_multiples a lst =
    let rec remmult multa li accu = function
        []         -> rev accu
      | head::tail ->
          if multa = head
          then remmult (a*(hd li)) (tl li)  accu      tail
          else remmult   multa        li (head::accu) tail
    in
    remmult (a * a) lst [] lst
  in
  let rec first_primes accu ll =
    let a = hd ll in 
    if a * a > borne then (rev accu) @ ll 
    else first_primes (a::accu) (remove_multiples a (tl ll))
  in
  let start_list =
(* Hard code of the differences of consecutive numbers that are prime*)
(* with 2 3 5 7 starting with 11... *) 
    let rec lrec = 2 :: 4 :: 2 :: 4 :: 6 :: 2 :: 6 :: 4 :: 2 :: 4 :: 6
      :: 6 :: 2 :: 6 :: 4 :: 2 :: 6 :: 4 :: 6 :: 8 :: 4 :: 2 :: 4 :: 2
      :: 4 :: 8 :: 6 :: 4 :: 6 :: 2 :: 4 :: 6 :: 2 :: 6 :: 6 :: 4 :: 2
      :: 4 :: 6 :: 2 :: 6 :: 4 :: 2 :: 4 :: 2 :: 10 :: 2 :: 10 :: lrec 
    and listPrime2357 a llrec accu =
      if a > borne then rev accu
      else listPrime2357 (a + (num (hd llrec))) (tl llrec) (a::accu)
    in
    listPrime2357 (num 11) lrec []
  in
  first_primes [(num 7);(num 5);(num 3);(num 2)] start_list;;

注意OCaml允许循环链接列表的好处。

Note the nice trick that OCaml allows for cyclic linked list.

这篇关于车轮分解的Eratosthenes筛的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆