Performance 这是一个好的素性检查解决方案吗?

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

我写这段代码是为了检查一个数字是否是素数(对于高达10^9+7的数字)

这是一个好方法吗??
这个的时间复杂度是多少

我所做的是制作了一个
无序集
,它将素数存储到
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