Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 轮因式分解法筛选埃拉斯托烯_C++_Algorithm_Primes_Sieve Of Eratosthenes_Wheel Factorization - Fatal编程技术网

C++ 轮因式分解法筛选埃拉斯托烯

C++ 轮因式分解法筛选埃拉斯托烯,c++,algorithm,primes,sieve-of-eratosthenes,wheel-factorization,C++,Algorithm,Primes,Sieve Of Eratosthenes,Wheel Factorization,我正在实现一个相当快的素数生成器,通过对其进行一些优化,我获得了一些不错的结果。特别是,在算法的初始部分,我以这种方式跳过了2和3的所有倍数: 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<

我正在实现一个相当快的素数生成器,通过对其进行一些优化,我获得了一些不错的结果。特别是,在算法的初始部分,我以这种方式跳过了2和3的所有倍数:

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;
}
模板
void PrimeGenerator::factorize()
{
尺寸c=2;
m_筛[2]=1;
m_筛[3]=1;

对于(sizeti=5;i您可以更进一步

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允许循环链表的好技巧。

为IBM工作的澳大利亚数学家保罗·普里查德(Paul Pritchard)在20世纪80年代开发了一系列轮筛。我在上讨论了其中的一个,包括手工操作的示例和Scheme中的一个实现。它太大了,无法在这里讨论。您应该知道,尽管渐近线ic的复杂度比Eratosthenes的筛子要小,实施细节通常会使其在实践中变得更慢。

2*3*5=30
辐条=2,3,4,5,6,8,9,10,12,15,16,18,20,24,30
辐条之间的数字:1,7,11,13,17,19,23,25,29

int[] gaps = [6,4,2,4,2,4,2,4];
int[] primes = [2,3,5];
int max = 9001;
int counter, max_visited;
while(max_visited < max) {
  int jump = gaps[counter];
  counter = counter + 1 % gaps.length;
  max_visited += jump;
}
int[]间隙=[6,4,2,4,2,4,2,4];
int[]素数=[2,3,5];
int max=9001;
int计数器,最大访问量;
同时(最大访问量<最大访问量){
int jump=间隙[计数器];
计数器=计数器+1%间隙。长度;
最大访问次数+=跳跃;
}
这有用吗

或者,这可能是您想要的伪代码:

primes = [2,3,5];
product = multiply(primes);//imaginary function that returns 30
wheel = new int[product];
foreach(prime in primes)
  for(int x = 1; x <= product/prime; x++)
    wheel[prime*x] = 1;
return wheel
primes=[2,3,5];
乘积=乘法(素数);//返回30的虚函数
车轮=新的整数[产品];
foreach(素数中的素数)

对于(int x=1;x有一个更好的优化(对于您的变体,它需要O(n)操作而不是O(n log n)),但是它需要更多的内存(使用n+n/log n内存而不是n)

如果你仍然想继续你的优化并考虑P1、P2、…、PN的素数,你应该把所有的数字从0写到P1*P2*…*PN(如果你决定不使用素数,使用LCM),检查它们中的哪一个满足下列系统: x!=0(模块p1) x!=0(模p2) ... x!=0(模件编号)


然后你应该找出这些数字之间的所有差距,并将这些差距编成一个数组来使用它们。

你的问题是什么?你在寻找erathosthenes代码的筛选吗?答案中有一个Haskell实现。如果我不清楚,我很抱歉:我想跳过所有2、3和5的倍数,就像我已经跳过2和3的倍数一样。不,我不需要eratosthenes代码的筛选分离素数候选者的映射(不能被因子整除的数字)从实际的筛选算法中筛选出位。带有2、3和5的轮子特别方便,因为30个数字的每段有8个候选,可以方便地存储在一个字节中。谢谢。我不懂那种语言,但我会尽力理解:)重要的部分是差异的硬编码列表。2,4,2,4,6=>11+2=3,13+4=16,17+2=19,19+4=23,23+6=29…我正在删除23+5的倍数。有办法计算这些值吗?是的!我没有奇迹般地得到这些值!对不起,太诱人了;-)从11开始,列出11到11+2*3*5*7之间不能被2,3,5,7整除的所有数字,并记录差异。然后从11+2*3*5*7重复到11+(2*3*5*7)*以此类推……使用2、3和5,我在Java中得到了因子3的加速。2-4轮子编程更简单:2*3=6。
step=6-step
给出了2、4、2、4……的步骤。记住从5开始,分别测试除数2和3。