用c++找出质数最快的算法是什么?我已经使用了sieve的算法,但我仍然希望它更快!
当前回答
i wrote it today in C,compiled with tcc, figured out during preparation of compititive exams several years back. don't know if anyone already have wrote it alredy. it really fast(but you should decide whether it is fast or not). took one or two minuts to findout about 1,00,004 prime numbers between 10 and 1,00,00,000 on i7 processor with average 32% CPU use. as you know, only those can be prime which have last digit either 1,3,7 or 9 and to check if that number is prime or not, you have to divide that number by previously found prime numbers only. so first take group of four number = {1,3,7,9}, test it by dividing by known prime numbers, if reminder is non zero then number is prime, add it to prime number array. then add 10 to group so it becomes {11,13,17,19} and repeat the process.
#include <stdio.h>
int main() {
int nums[4]={1,3,7,9};
int primes[100000];
primes[0]=2;
primes[1]=3;
primes[2]=5;
primes[3]=7;
int found = 4;
int got = 1;
int m=0;
int upto = 1000000;
for(int i=0;i<upto;i++){
//printf("iteration number: %d\n",i);
for(int j=0;j<4;j++){
m = nums[j]+10;
//printf("m = %d\n",m);
nums[j] = m;
got = 1;
for(int k=0;k<found;k++){
//printf("testing with %d\n",primes[k]);
if(m%primes[k]==0){
got = 0;
//printf("%d failed for %d\n",m,primes[k]);
break;
}
}
if(got==1){
//printf("got new prime: %d\n",m);
primes[found]= m;
found++;
}
}
}
printf("found total %d prime numbers between 1 and %d",found,upto*10);
return 0;
}
其他回答
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.
寻找因素的解决方案:
def divisors(integer):
result = set()
i = 2
j = integer/2
while(i <= j):
if integer % i == 0:
result.add(i)
#it dont need to
result.add(integer//i)
i += 1
j = integer//i
if len(result) > 0:
return f"not prime {sorted(result)}"
else:
return f"{integer} is prime"
—测试---- 导入的时间
start_time = time.time()
print(divisors(180180180180))
print("--- %s seconds ---" % (time.time() - start_time))
——0.06314539909362793秒——
start_time = time.time()
print(divs(180180180180180))
print("--- %s seconds ---" % (time.time() - start_time))
——1.5997519493103027秒——
start_time = time.time()
print(divisors(1827))
print("--- %s seconds ---" % (time.time() - start_time))
——0.0秒——
start_time = time.time()
print(divisors(104729))
print("--- %s seconds ---" % (time.time() - start_time))
——0.0秒——
下面的代码:
def divs(integer):
result = set()
i = 2
j = integer / 2
loops = 0
while (i <= j):
if integer % i == 0:
print(f"loops:{loops}")
return f"{integer} is not a prime"
i += 1
j = integer // i
loops += 1
print(f"loops:{loops}")
return f"{integer} is prime"
——测试——
start_time = time.time()
print(divs(180180180180180180180180))
print("--- %s seconds ---" % (time.time() - start_time))
——0.0秒——
这是找到从1到n的所有质数的最快算法(在我的电脑上,它只花了0.004秒就找到了从1到1000000的所有质数)。
#include <iostream>
#include <fstream>
using namespace std;
double FindPrime(bool* array, int size){
clock_t start;
double runtime;
for (int i = 2; i < size; i++)
array[i] = true;
start = clock();
for (int i = 2; i <= size; i++)
if (array[i])
for (int j = 2 * i; j < size; j += i)
array[j] = false;
runtime = (double)(clock() - start) / CLOCKS_PER_SEC;
return runtime;
}
int main() {
ofstream fout("prime.txt");
int n = 0;
cout << "Enter the upper limit of prime numbers searching algorithm:";
cin >> n;
bool* array = new bool[n + 1];
double duration = FindPrime(array, n + 1);
printf("\n%f seconds.\n", duration);
for (int i = 2; i <= n; i++)
if (array[i])
fout << i << endl;
fout.close();
return 0;
}
这是我一直在玩的埃拉托色尼筛子的Python实现。
def eratosthenes(maximum: int) -> list[int | None]:
"""
Find all the prime numbers between 2 and `maximum`.
Args:
maximum: The maximum number to check.
Returns:
A list of primes between 2 and `maximum`.
"""
if maximum < 2:
return []
# Discard even numbers by default.
sequence = dict.fromkeys(range(3, maximum+1, 2), True)
for num, is_prime in sequence.items():
# Already filtered, let's skip it.
if not is_prime:
continue
# Avoid marking the same number twice.
for num2 in range(num ** 2, maximum+1, num):
# Here, `num2` might contain an even number - skip it.
if num2 in sequence:
sequence[num2] = False
# Re-add 2 as prime and filter out the composite numbers.
return [2] + [num for num, is_prime in sequence.items() if is_prime]
在一台简陋的三星Galaxy A40上,该代码大约需要16秒才能输入10000000个数字。
欢迎提出建议!
有一个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,然后测试剩余的部分。