用c++找出质数最快的算法是什么?我已经使用了sieve的算法,但我仍然希望它更快!
当前回答
另一个Python实现比死亡面具推销员的答案更直接,也更快:
import numpy as np
def prime_numbers(limit: int) -> list[int]:
"""Provide a list of all prime numbers <= the limit."""
is_prime = np.full((limit + 1, ), True)
is_prime[0:2] = False
for n in range(2, limit + 1):
if is_prime[n]:
is_prime[n**2::n] = False
return list(np.where(is_prime)[0])
你可以进一步优化,例如,排除2,或者硬编码更多质数,但我想保持简单。
*示例运行时比较(注意:我使用了其他实现的优化形式,见我的评论):
其他回答
Rabin-Miller是一个标准的概率质数检验。(你运行K次,输入数字要么肯定是合数,要么可能是素数,误差概率为4-K。(经过几百次迭代,它几乎肯定会告诉你真相)
拉宾·米勒有一个非概率(确定性)的变体。
The Great Internet Mersenne Prime Search (GIMPS) which has found the world's record for largest proven prime (274,207,281 - 1 as of June 2017), uses several algorithms, but these are primes in special forms. However the GIMPS page above does include some general deterministic primality tests. They appear to indicate that which algorithm is "fastest" depends upon the size of the number to be tested. If your number fits in 64 bits then you probably shouldn't use a method intended to work on primes of several million digits.
我最近写了这段代码来求数字的和。它可以很容易地修改,以确定一个数字是否是质数。基准测试在代码之上。
// built on core-i2 e8400
// Benchmark from PowerShell
// Measure-Command { ExeName.exe }
// Days : 0
// Hours : 0
// Minutes : 0
// Seconds : 23
// Milliseconds : 516
// Ticks : 235162598
// TotalDays : 0.00027217893287037
// TotalHours : 0.00653229438888889
// TotalMinutes : 0.391937663333333
// TotalSeconds : 23.5162598
// TotalMilliseconds : 23516.2598
// built with latest MSVC
// cl /EHsc /std:c++latest main.cpp /O2 /fp:fast /Qpar
#include <cmath>
#include <iostream>
#include <vector>
inline auto prime = [](std::uint64_t I, std::vector<std::uint64_t> &cache) -> std::uint64_t {
std::uint64_t root{static_cast<std::uint64_t>(std::sqrtl(I))};
for (std::size_t i{}; cache[i] <= root; ++i)
if (I % cache[i] == 0)
return 0;
cache.push_back(I);
return I;
};
inline auto prime_sum = [](std::uint64_t S) -> std::uint64_t {
std::uint64_t R{5};
std::vector<std::uint64_t> cache;
cache.reserve(S / 16);
cache.push_back(3);
for (std::uint64_t I{5}; I <= S; I += 8)
{
std::uint64_t U{I % 3};
if (U != 0)
R += prime(I, cache);
if (U != 1)
R += prime(I + 2, cache);
if (U != 2)
R += prime(I + 4, cache);
R += prime(I + 6, cache);
}
return R;
};
int main()
{
std::cout << prime_sum(63210123);
}
I know it's somewhat later, but this could be useful to people arriving here from searches. Anyway, here's some JavaScript that relies on the fact that only prime factors need to be tested, so the earlier primes generated by the code are re-used as test factors for later ones. Of course, all even and mod 5 values are filtered out first. The result will be in the array P, and this code can crunch 10 million primes in under 1.5 seconds on an i7 PC (or 100 million in about 20). Rewritten in C it should be very fast.
var P = [1, 2], j, k, l = 3
for (k = 3 ; k < 10000000 ; k += 2)
{
loop: if (++l < 5)
{
for (j = 2 ; P[j] <= Math.sqrt(k) ; ++j)
if (k % P[j] == 0) break loop
P[P.length] = k
}
else l = 0
}
有一个100%的数学测试可以检查一个数字P是质数还是合数,叫做AKS质数测试。
概念很简单:给定一个数字P,如果(x-1)^P - (x^P-1)的所有系数都能被P整除,那么P是一个质数,否则它是一个合数。
例如,给定P = 3,会给出多项式:
(x-1)^3 - (x^3 - 1)
= x^3 + 3x^2 - 3x - 1 - (x^3 - 1)
= 3x^2 - 3x
系数都能被3整除,所以这个数是素数。
P = 4不是质数的例子是:
(x-1)^4 - (x^4-1)
= x^4 - 4x^3 + 6x^2 - 4x + 1 - (x^4 - 1)
= -4x^3 + 6x^2 - 4x
这里我们可以看到系数6不能被4整除,因此它不是质数。
多项式(x-1)^P有P+1项,可以用组合法找到。因此,这个测试将在O(n)个运行时间内运行,所以我不知道这有多有用,因为你可以简单地从0到p遍历I,然后测试剩余的部分。
I found this solution pretty fast but it comes with consequences, So this is called Fermat's Little Theorem. If we take any number p and put that in (1^p)-1 or (2^p)-2...(n^p)-n likewise and the number we get is divisible by p then it's a prime number. Talking about consequences, it's not 100% right solution. There are some numbers like 341(not prime) it will pass the test with (2^341)-2 but fails on (3^341)-3, so it's called a composite number. We can have two or more checks to make sure they pass all of them. There is one more kind of number which are not prime but also pass all the test case:( 561, 1729 Ramanujan taxi no etc.
好消息是:在前250亿个数字中,只有2183不符合这个要求 的情况。
#include <iostream>
#include <math.h>
using namespace std;
int isPrime(int p)
{
int tc = pow(2, p) - 2;
if (tc % p == 0)
{
cout << p << "is Prime ";
}
else
{
cout << p << "is Not Prime";
}
return 0;
}
int main()
{
int p;
cin >> p;
isPrime(p);
return 0;
}