python1-n之间的素数输出_编程计算并输出1~n之间所有素数之和

更新时间:2023-06-22 03:36:07 阅读: 评论:0

{
j = bn[ i ] <
l = j + bn[ i ];        do
{            map[l / (BITMAPSIZE * 2)] |= (1 <> 1) % BITMAPSIZE));
l += j;
} while (l
}
c = 0;    for (i = 1; i
{
i++;        if ((map[i / BITMAPSIZE] & (1 <
{
公斤的英文
c++;
}
i++;        if ((map[i / BITMAPSIZE] & (1 <
{
c++;
}
}
mature woman
printf("1~1000000000 number: %d\n", c);    return 0;
}
本质就是素数筛,只不过⽤了两遍。
第⼀组循环统计根号⼗亿内的素数。正常的筛法应⽤。
第⼆组循环⽤上⾯计算出来的素数筛剩余的范围。
这⾥⽐较有意思的地⽅就是它节省内存⽤的技巧。1.使⽤位作标志。2.它删掉了所有的偶数。也就是说第1位表⽰3,第2位表⽰5等等。也正因如此它的筛的步长才是两倍的素数,⽽起始步长是3倍的素数。
第三组循环就是统计标志位了。
2.⼤⽜算法⼆。----bccn⾥⾯的beyondyf版主,杨⼤哥的算法。
在上⼀算法的基础上进⼀步优化,代码量是少了。同时,也更难懂了。
#include#define RANGE    1000000000
char P[RANGE / 16 + 1];
int main()
{
int i, j, t, c = 1;
for(i = 3; i <= RANGE; i += 2)        if(!(P[i >> 4] & (1 <> 1 & 7))))
for(c++, t = i + i, j = t + i; j > 0 && j <= RANGE; j += t)                P[j >> 4] |= 1 <> 1 & 7);
printf("%d\n", c);
return 0;gettogether
}
要找出⼀个数的因⼦,其实不需要检查 2→k,只要从 2->sqrt(k),就可以了。所有,我们筛法⾥,其实只要筛到sqrt(n)就已经找出所有的素数了,其中n为要搜索的范围。
另外,我们不难发现,每找到⼀个素数 k,就⼀次删除 2k, 3k, 4k,..., ik,不免还是有些浪费,因为2k已经在找到素数2的时候删除过
了,3k已经在找到素数3的时候删除了。因此,当 i<k 时,都已经被前⾯的素数删除过了,只有那些最⼩的质因⼦是k的那些数还未被删除过,所有,就可以直接从 k*k 开始删除。
再有,所有的素数中,除了 2 以外,其他的都是奇数,那么,当 i 是奇数的时候,ik 就是奇数,此时
k*k+ik 就是个偶数,偶数已经被2删除了,所有我们就可以以2k为单位删除步长,依次删除 k*k, k*k+2k, k*k+4k, ...。
我们都清楚,在前⾯⼀⼩段范围内,素数是⽐较集中的,⽐如 1→100 之间就有25个素数。越到后⾯就越稀疏。
因为这些素数本⾝值⽐较⼩,所以搜索范围内,⼤部分数都是它们的倍数,⽐如搜索 1→100,这 100 个数。光是 2 的倍数就有 50
个,3 的倍数有 33 个,5的倍数 20 个,7 的倍数 14 个。我们只需搜索到7就可以,因此⼀共做删除操作50+33+20+14=117次,⽽2 和 3 两个数就占了 83 次,这未免太浪费时间了。
所以我们考虑,能不能⼀开始就排除这些⼩素数的倍数,这⾥⽤ 2 和 3 来做例⼦。
如果仅仅要排除 2 的倍数,数组⾥只保存奇数:1、3、5...,那数字 k 的坐标就是 k/2。
如果我们要同时排除 2 和 3 的倍数,因为 2 和 3 的最⼩公倍数是 6,把数字按 6 来分组:6n, 6n+1, 6n+2, 6n+3, 6n+4, 6n+5。其中6n, 6n+2, 6n+4 是 2 的倍数,6n+3 是 3 的倍数。所以数组⾥将只剩下 6n+1 和 6n+5。n 从 0 开始,数组⾥的数字就⼀次是 1, 5, 7, 11, 13, 17...。
现在要解决的问题就是如何把数字 k 和它的坐标 i 对应起来。⽐如,给出数字 89,它在数组中的下标是多少呢?不难发现,其实上⾯的序列,每两个为⼀组,具有相同的基数 n,⽐如 1 和 5 ,同是 n=0 那组数,6*0+1 和 6*0+5;31 和 35 同是n=5那组,6*5+1 和
6*5+5。所以数字按6分组,每组2个数字,余数为5的数字在后,所以坐标需要加 1。
所以 89 在第 89/6=14 组,坐标为 14*2=28,⼜因为 89%6==5,所以在所求的坐标上加 1,即 28+1=29,最终得到 89 的坐标
i=29。同样,找到⼀个素数 k 后,也可以求出 k*k 的坐标等,就可以做筛法了。
这⾥,我们就需要⽤ k 做循环变量了,k 从 5 开始,交替与 2 和 4 相加,即先是 5+2=7,再是 7+4=11,然后⼜是 11+。这⾥我们可以再设⼀个变量gab,初始为 4,每次做 gab = 6 - gab,k += gab。让gab在2和4之间交替变化。另外,2 和 4 都是 2 的幂,⼆进制分别为10和100,6的⼆进制位110,所以可以⽤ k += gab ^= 6来代替。参考代码:
overall是什么意思
gab = 4;
shlong
for (k = 5; k * k <= N; k += gab ^= 6)
{
...  }
gab = 4;
for (k = 5; k * k <= N; k += gab ^= 6)
{    ...}
但我们⼀般都采⽤下标 i 从 0→x 的策略,如果⽤ i ⽽不⽤ k,那应该怎么写呢?
由优化策略(1)可知,我们只要从 k2 开始筛选。 n=i/2,我们知道了 i 对应的数字 k 是素数后,根据(2),那如何求得 k2的坐标 j 呢?这⾥假设 i 为偶数,即 k=6n+1。
k2 = (6n+1)*(6n+1) = 36n2 + 12n + 1,其中 36n2+12n = 6(6n2+2n) 是6的倍数,所以 k2除 6 余 1。
所以 k2的坐标 j = k2/6*2 = 12n2+4n。
由优化策略(2)可知,我们只要依次删除 k2+2l×k, l = 0, 1, 2...。即 (6n+1)×(6n+1+2l)。
我们发现,但l=1, 4, 7...时,(6n+1+2l)是3的倍数,不在序列中。所以我们只要依次删除 k2, k2+4l, k2+,⼜是依次替换2和4。
为了简便,我们可以⼀次就删除 k2和 k2+4l 两项,然后步长增加6l。所以我们需要求 len=4l 和 stp=6l。不过这⾥要注意⼀点,k2+4k= (6n+1)*(6n+5),除以6的余数是5,坐标要加1。
len = k*(k+4)/6*2 - k2/6*2 = (6n+1)*(6n+1+4)/6*2+1 - (6n+1)*(6n+1)/6*2 = (12n2+12n+1) - (12n2+4n) = 8n+1;
finish的过去式
billboard中文stp = k*(k+6)/6*2 - k2/6*2 = 12n+2;
最终,我们得到:
len = 8n+1;mis
stp = 12n+2;
j = 12n2+4n;
同理可以求出 k=6n+5 时的情况:
len = 4n+3;
stp = 12n+10;
j = 12n2+20n+8;
下⾯的代码在实现上⽤了位运算,可能有点晦涩。
#include #include #include #define N 1000000000
#define size (N/6*2 + (N%6 == 5? 2: (N%6>0)))
int p[size / 32 + 1] = {1};
unconditionalint creat_prime(void)
{
int i, j;
int len, stp;
int c = size + 1;
for (i = 1; ((i&~1)<<1) * ((i&~1) + (i>>1) + 1)
{        if (p[i >> 5] >> (i & 31) & 1) continue;
len = (i & 1)? ((i&~1)<<1) + 3: ((i&~1)<<2) + 1;        stp = ((i&~1)<<1) + ((i&~1)<<2) + ((i & 1)? 10: 2);        j = ((i&~1)
<<1) * (((i&~1)>>1) + (i&~1) + 1) + ((i & 1)? ((i&~1)<<3) + 8 + len: len);        for (; j
{            if (p[j >> 5] >> (j & 31) & 1 ^ 1)
p[j >> 5] |= 1L <> 5] >> ((j-len) & 31) & 1 ^ 1)
湖北省英语三级成绩查询p[(j-len) >> 5] |= 1L <
}        if (j - len > 5] >> ((j-len) & 31) & 1 ^ 1))
p[(j-len) >> 5] |= 1L <
}    return c;
}int main(void)

本文发布于:2023-06-22 03:36:07,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/90/153257.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:素数   删除   坐标   数组   数字   开始
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图