查找两个大数 x 和 y 之间的素数数的最快方法
fastest method for finding number of prime numbers between two large numbers x and y
here x,y<=10^12 and y-x<=10^6
我从左到右循环并检查每个数字的素数。当 x 和 y 有点像 10^11 和 10^12 时,这种方法非常慢。我 hv 将所有素数存储到 10^6..我可以使用它们来查找 10^10-10^12 等巨大值之间的素数吗?
for(i=x;i<=y;i++)
{
num=i;
if(check(num))
{
res++;
}
}
我的支票功能
int check(long long int num)
{
long long int i;
if(num<=1)
return 0;
if(num==2)
return 1;
if(num%2==0)
return 0;
long long int sRoot = sqrt(num*1.0);
for(i=3; i<=sRoot; i+=2)
{
if(num%i==0)
return 0;
}
return 1;
}
使用埃拉托色尼的分段筛。
也就是说,使用位集来存储 x
和 y
之间的数字,用 x
表示为偏移量,位设置为 [0,y-x)。然后对所有小于或等于y
平方 根的素数进行筛分(消除倍数)。那些留在集合中的数字是质数。
对于最多 1012 个y
,您必须用最多 106 个素数进行筛分,这在正确的实现中将花费不到一秒钟的时间。
该资源通过许多主要搜索算法来提高复杂性/效率。这是最好的描述,即PG7.8
(您必须翻译回C++,应该不会太难)
该算法通过从考虑中消除先前识别的素数的倍数来有效地选择潜在的素数,并且 最大限度地减少为验证 每个潜在素数的首要地位。同时选择效率 潜在的素数允许程序筛选更大范围的 每秒数 程序运行的时间越长,测试次数就越多 需要在每个潜在素数上执行的确实继续 上升,(但与其他算法相比,上升速度较慢)。 总之,这些过程为产生素数带来了更高的效率 数字,甚至生成 10 位验证素数 可以在PC上的合理时间内完成。
可以开发进一步的跳过集,以消除潜在素数的选择,这些素数可以由已经具有的每个素数分解 已被识别。虽然这个过程更复杂,但它可以是 概括并变得有些优雅。同时,我们可以 继续从测试素数集中消除每个素数 跳过集消除了倍数,最大限度地减少了 必须在每个潜在素数上执行的测试。
您可以使用埃拉托色尼筛子算法。此页面包含一些指向各种语言的实现的链接:https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes。
这是我对 Sieve of Erathostenes 的实现:
#include <string>
#include <iostream>
using namespace std;
const int k = 110000; //you can change this constant to whatever maximum int you would need to calculate
long int p[k]; //here we would store Sieve of Erathostenes from 2 to k
long int j;
void init_prime() //in here we set our array
{
for (int i = 2; i <= k; i++)
{
if (p[i] == 0)
{
j = i;
while (j <= k)
{
p[j] = i;
j = j + i;
}
}
}
/*for (int i = 2; i <= k; i++)
cout << p[i] << endl;*/ //if you uncomment this you can see the output of initialization...
}
string prime(int first, int last) //this is example of how you can use initialized array
{
string result = "";
for (int i = first; i <= last; i++)
{
if (p[i] == i)
result = result + to_str(i) + "";
}
return result;
}
int main() //I done this code some time ago for one contest, when first input was number of cases and then actual input came in so nocases means "number of cases"...
{
int nocases, first, last;
init_prime();
cin >> nocases;
for (int i = 1; i <= nocases; i++)
{
cin >> first >> last;
cout << prime(first, last);
}
return 0;
}
您也可以使用Erathostenes筛来计算阶乘。这实际上是我当天可以设法创建的筛子的最快解释(它可以在不到一秒钟的时间内计算出这个范围的筛子)
- 数数并选择 sqlite 中的前三名
- 查找数组中第一个最小值和最后一个最大值元素之间的算术平均值
- 在 Python 和 c++ 2d 数组初始化之间.这是怎麽?为什么呢?
- 介于 [固定数组] 和 [带内存分配的指针] 之间的性能
- 在两个结构之间共享数组
- 数数并说在C++中使用递归
- 在给定的整数数组中,可以找到在给定位置之间分类数组的整数之和
- 在MPI进程之间更新数组
- 合并排序问题,在方法之间传递数组
- 在两个函数之间发送数组C++
- 在结构C++之间传递数组
- 如何在分叉之间共享数组
- 如何将小数数组转换为二进制数数组
- 两个进程之间共享数组
- 在C++中的类之间发送数组
- 如何在c++中使用静态变量在不同的类之间共享数组
- 在VB之间传递数组.. NET和vc++
- 使用命名(fifo)管道在python和c++之间传输数组(图像)
- C++函数调用之间更改数组内容
- 通过属性在c++和QML之间共享数组或列表