使用欧拉筛法求素数和
来源:互联网 发布:企业seo外包 编辑:程序博客网 时间:2024/06/10 03:31
上一次写到了厄拉多塞筛法,说到厄拉多塞筛法随着计算上限的成倍增加,计算时间也会成倍增加。
这次的欧拉筛法在时间这方面会比厄拉多塞筛法好很多。
先上代码:
#include <cstdio>#include <cstring>#include <stdlib.h>#include <stdint.h>#define MAX 1000000int main(){uint64_t* prime;prime = (uint64_t*)malloc(MAX*sizeof(uint64_t));memset(prime, 0, MAX);bool isprime[MAX];memset(isprime, true, sizeof(isprime));uint64_t index = 0;for (uint64_t i = 2; i < MAX; ++i){if (isprime[i]){prime[index] = i;++index;}for (uint64_t j = 0; j < index && i * prime[j] < MAX; ++j){isprime[i*prime[j]] = false;if (i % prime[j] == 0){break;}}}uint64_t sum = 0;for (uint64_t i = 0; i < index; ++i){sum += prime[i];}printf("%llu\n", sum);free(prime);return 0;}欧拉筛法的思路和厄拉多塞筛法很像,素数的倍数标记成合数,但是标记的方法有区别。
欧拉筛法把数字i和已知的所有素数相乘,然后把结果标记为合数。
重要的是计算i%prime[j]是否为0,如果为0则break掉现在的循环。
这一步的意思是,每一个合数只被它最小的素数因数排除一次。
比如说12,12的第一次可能被排除的情况是i=4,此时经过for循环以后,因为4*prime[0]=8,所以首先把8给排除掉,然后因为4可以整除prime[0]也就是2,所以break掉for循环,也就是没有排除掉12.
实际上12会在6的时候被排除,此时6在排除过12以后,break掉for循环,不会排除18,因为18是需要9来排除的。
这样在厄拉多塞筛法中重复被排除的12,18之类的数字就不会被重复排除,算法的效率也就得到了提高。
但是我在想要把MAX设置为十亿,跟厄拉多塞筛法做一个比拼时,发现了一个问题,就是欧拉筛法需要一个数组来保存目前已知的所有素数。
但是即使我已经用了malloc,但是还是不能分配到这么大的内存,直接StackOverflow了。
所以先把算法的实现方法写在这里,等我Google到方法后再修改。
0 0
- 使用欧拉筛法求素数和
- 使用筛法找素数 HOJ 2098 分拆素数和
- 使用厄拉多塞筛法计算素数的和
- 使用for循环和%求取素数
- 素数和
- 素数和
- 素数和
- 素数和
- 素数和
- 素数和
- 素数和
- 素数和
- 素数和
- 素数和
- 求素数和 bjfu1020 素数
- 最大素数和最小素数
- 素数筛选 求素数和
- 实验5-5 使用函数求素数和 (20分)
- java序列化
- LeetCode -- Best Time to Buy and Sell Stock II
- jquery $(document).ready() 与window.onload的区别
- 第1篇,移动互联网究竟是何方神圣还是一个妖魔鬼怪?
- Android Fragment解析
- 使用欧拉筛法求素数和
- JavaScript添加事件
- 9 Palindrome Number
- 吉哥系列故事——完美队形II(hdu4513+Manacher)
- LeetCode 06 ZigZag Conversion
- Terrible Sets(单调栈,一开始还被题目描述吓到了,理解样例后发现就是纸老虎题。。。)
- Safecracker(HDU1015 全排列回溯)
- Android Listview中的simpleadapter类型没有触发item的点击事件的解决办法
- ADOdotNET