检查数字是否为素数的更好方法是什么?

时间:2011-07-18 04:07:57

标签: c++ math numbers

  

可能重复:
  Checking if an int is prime more efficiently

bool isPrime(int num)
{
    for(int i = 2; i <= (num/2)+1; i++)
    {
        if(num % i == 0)
        {
            return false;
        }
    }
    return true;
}

我看过维基百科,但我不了解它描述的任何快速素性测试。

6 个答案:

答案 0 :(得分:3)

首先,您只需要在i * i <= num时进行迭代。

之后,您可能会注意到测试一个数字是否为2的倍数只是一个小测试。一旦你知道数字不均匀,你知道没有偶数因素,所以你可以跳过测试。

这导致:

bool isPrime(int num)
{
    if (num < 4) return true;
    if (~num & 1) return false;
    for( int i = 3; i * i <= num; i += 2 )
    {
        if (num % i == 0) return false;
    }
    return true;
}

答案 1 :(得分:1)

如果您的输入集特别小,那么您可以使用sieve of erathones创建素数,然后在该筛子上进行素数测试。这是您算法之后的下一步。

您可以进行许多性能调整,以便更快地进行素性测试,例如跳过因子2和3等。

答案 2 :(得分:0)

更好的方法(如果你想加速你的应用程序)是在第一个素数预先计算,将它们添加到数组中,只搜索你的数字,或检查数组元素的除法。

另外,您可以检查num % i == 0不是num/2,但最多sqrt(num)

PS:

if(num % i == 0)
        {
            return true;
        }

你必须返回false:)

答案 3 :(得分:0)

对于比你的方法更快的东西,你应该使用Eratosthenes的Sieve等建立一个素数表(生成素数至少与你正在测试的数量一样)。然后使用二进制搜索查看您的数字。如果你保留桌子,如果你以后需要查找更高的数字,你可以逐步建立它。

Gogo动态编程。 : - )

答案 4 :(得分:0)

你可以采取一些措施来加快速度:

不是从2开始并执行i++,而是检查它是否在第一个开头,如果不是,则从3开始并将i递增2:

if (num % 2 == 0) {
   return false;
}
for (int i = 3; i <= sqrt(num); i += 2) { ... }

此示例中的另一个提示是将您的上限设置为数字的平方根,而不是num/2

需要进行一些设置的另一件事是使用prime sieve来快速测试您的号码是否为素数。

答案 5 :(得分:0)

米勒 - 拉宾测试实施相对简单,虽然证明它是正确的要困难得多。基本上,你多次运行这个测试;每次,您在2和您的号码之间选择一个随机的“见证”号码,然后运行算法。测试将告诉你,你的号码肯定是复合的(不是素数)或者它可能是素数(每次的概率为1/4,这是错误的),所以如果你用十个随机证人进行十次测试并得到“可能是素数“每次,机会都不到百万分之一,这个数字实际上是复合的。

Wikipedia在伪代码中有一个实现:http://en.wikipedia.org/wiki/Miller-Rabin_test#Algorithm_and_running_time