Performance 这是一个好的素性检查解决方案吗?
我写这段代码是为了检查一个数字是否是素数(对于高达10^9+7的数字) 这是一个好方法吗??Performance 这是一个好的素性检查解决方案吗?,performance,optimization,primes,c++14,Performance,Optimization,Primes,C++14,我写这段代码是为了检查一个数字是否是素数(对于高达10^9+7的数字) 这是一个好方法吗?? 这个的时间复杂度是多少 我所做的是制作了一个无序集,它将素数存储到sqrt(n) 检查一个数字是否为素数时,首先检查其是否小于表中的最大值。 如果较小,则在表中搜索,因此在这种情况下复杂性应为O(1)。 如果大于,则使用包含素数的数字集合中的数字进行整除性测试 #include<iostream> #include<set> #include<math.h> #inc
这个的时间复杂度是多少 我所做的是制作了一个
无序集
,它将素数存储到sqrt(n)
检查一个数字是否为素数时,首先检查其是否小于表中的最大值。
如果较小,则在表中搜索,因此在这种情况下复杂性应为
O(1)
。如果大于,则使用包含素数的数字集合中的数字进行整除性测试
#include<iostream>
#include<set>
#include<math.h>
#include<unordered_set>
#define sqrt10e9 31623
using namespace std;
unordered_set<long long> primeSet = { 2, 3 }; //used for fast lookups
void genrate_prime_set(long range) //this generates prime number upto sqrt(10^9+7)
{
bool flag;
set<long long> tempPrimeSet = { 2, 3 }; //a temporay set is used for genration
set<long long>::iterator j;
for (int i = 3; i <= range; i = i + 2)
{
//cout << i << " ";
flag = true;
for (j = tempPrimeSet.begin(); *j * *j <= i; ++j)
{
if (i % (*j) == 0)
{
flag = false;
break;
}
}
if (flag)
{
primeSet.insert(i);
tempPrimeSet.insert(i);
}
}
}
bool is_prime(long long i,unordered_set<long long> primeSet)
{
bool flag = true;
if(i <= sqrt10e9) //if number exist in the lookup table
return primeSet.count(i);
//if it doesn't iterate through the table
for (unordered_set<long long>::iterator j = primeSet.begin(); j != primeSet.end(); ++j)
{
if (*j * *j <= i && i % (*j) == 0)
{
flag = false;
break;
}
}
return flag;
}
int main()
{
//long long testCases, a, b, kiwiCount;
bool primeFlag = true;
//unordered_set<int> primeNum;
genrate_prime_set(sqrt10e9);
cout << primeSet.size()<<"\n";
cout << is_prime(9999991,primeSet);
return 0;
}
#包括
#包括
#包括
#包括
#定义sqrt10e9 31623
使用名称空间std;
无序_集素数集={2,3}//用于快速查找
void genrate_prime_set(长范围)//这将生成最高为sqrt(10^9+7)的素数
{
布尔旗;
set tempPrimeSet={2,3};//临时集合用于生成
集合::迭代器j;
对于(int i=3;i,我只能建议一种使用Java中的库函数来检查数字的素性的方法。至于其他问题,我没有任何答案
java.math.BigInteger.isProbablePrime(int确定性)如果这个BigInteger可能是prime,则返回true;如果它肯定是复合的,则返回false≤ 0,返回true。您应该尝试在代码中使用它。所以请尝试用Java重写它
参数
确定性-调用者愿意容忍的不确定性度量:如果调用返回true,则此BigInteger为素数的概率超过(1-1/2^确定性)。此方法的执行时间与此参数的值成比例
返回值
如果这个BigInteger可能是素数,则该方法返回true;如果它肯定是复合的,则返回false
例子
下面的示例显示math.BigInteger.isProbablePrime()方法的用法
输出
在我看来,这并不是做手头工作的一种特别有效的方法
虽然最终可能不会有太大的区别,但生成所有素数到某个特定极限的有效方法显然是使用一个筛子——埃拉托斯烯的筛子简单而快速。有几个修改可以更快,但对于你正在处理的小尺寸,它们可能不值得
它们通常以比您当前使用的更有效的格式生成输出。特别是,您通常只需为每个可能的素数(即每个奇数)指定一位,如果该数是复合数,则最终为零,如果该数是素数,则为一位(当然,如果您愿意,可以反转此意义)
因为从3到31623的每个奇数只需要一位,所以只需要16K位,或者2K字节——按照现代标准,这是一个非常小的内存量(特别是:足够小,可以很容易地放入一级缓存)
由于位是按顺序存储的,因此计算和测试的因子不超过要测试的数字的平方根,而不是针对表中的所有数字进行测试(包括那些大于要测试的数字平方根的数字,这显然是浪费时间)。这还优化了对内存的访问,以防其中一些不在缓存中(即,您可以按顺序访问所有数据,使硬件预取器的使用尽可能简单)
如果你想进一步优化,我会考虑使用筛选器找到所有的素数高达109 + 7,并查找输入。这是否是赢将取决于(沉重)根据您可能收到的查询数量。快速检查表明,一个简单的Eratosthenes筛实现可以在大约17秒内找到最多109个素数。之后,每个查询(当然)基本上是瞬时的(即,单个内存读取的成本)。这确实需要大约120兆字节的内存才能得到筛选结果,这曾经是一个主要考虑因素,但(在相当有限的系统上除外)通常不再需要了。
非常简短的回答:从“米勒·拉宾”这个词开始,对这个主题进行研究
简而言之,答案是否定的:
- 寻找一个数字的因子是检查素数的一个糟糕的方法
- 彻底地搜索素数是寻找因子的糟糕方法
- 特别是如果你搜索每个素数,而不仅仅是那些小于或等于这个数平方根的素数
- 对每一个素数进行素数测试是生成素数列表的糟糕方法
此外,如果需要将素数集作为一个参数,则应该通过引用而不是复制来获取它
注意:测试小素数以查看它们是否除以一个数是素数测试的有用的第一步,但通常只用于最小的素数,然后再切换到更好的方法不,这不是确定一个数是否为素数的一个很好的方法。下面是一个简单的素数测试的伪代码,该测试足以用于您的范围;我将把它留给您翻译成C++:
function isPrime(n)
d := 2
while d * d <= n
if n % d == 0
return False
d := d + 1
return True
函数isPrime(n)
d:=2
虽然D *这是一个很好的书面回答,但不幸的是,问题是用C++代码来帮助,而不是java。我建议删除这个答案,这样你就不会被反复投票。保持好的工作,但是要确保你的答案与问题的答案相匹配。谢谢你在StAccess上的帮助!谢谢。谢谢你的时间。但是我正在寻找算法实现,而不是做同样工作的库函数。谢谢你的帮助,先生。但是我仍然不知道如何使用位来实现筛子。请你详细说明一下,或者提供一些参考。@ShinMigami13:一个简单的方法是使用std::vector
。
7 is prime with certainity 1 is true
9 is prime with certainity 1 is false
9 is prime with certainity -1 is true
function isPrime(n)
d := 2
while d * d <= n
if n % d == 0
return False
d := d + 1
return True