除了使用Eratosthenes的Sieve方法生成素数外,我们还可以实现一种新算法来生成从1到N的素数。
知道可以从一个模式中跟踪所有≥5的质数可能令人惊讶:
让我们尝试理解该系列:
Series 1:
5 + 6 = 11
11 + 6 = 17
17 + 6 = 23
23 + 6 = 29
…
…
Series 2:
7 + 6 = 13
13 + 6 = 19
…
…
我们看到将6加到5并再次将6加到获得的结果中,我们可以获得另一个素数。类似地,将6加到7,然后再次将6加到获得的结果中。我们可以得到另一个素数。因此,我们可以推断出我们可以通过相同的过程获得所有素数。
但是,当我们继续将6与上一个结果相加以获得下一个质数时,我们会注意到一些不是质数的数。
例如:
13 + 6 = 19 (Prime Number)
19 + 6 = 25 (Composite Number; Say Pseudo Prime Number)
29 + 6 = 35 (Composite Number; Say Pseudo Prime Number)
我们可以将这些类型的复合数称为伪素数(作为素数出现,但实际上不是)。
现在,如果我们能够将这些伪素数与真实素数分开,我们就可以获得真实素数。使用4个重要方程,我们可以精确地跟踪所有这些伪素数并将它们与实素数分开。
将产生级数的方程为:
y = 6 * x ± 1
where x = 1, 2, 3, 4, 5, 6, 7, …
For example:
6 * (1) – 1 = 5 (Prime Number)
6 * (1) + 1 = 7 (Prime Number)
6 * (2) – 1 = 11 (Prime Number)
6 * (2) + 1 = 13 (Prime Number)
6 * (3) – 1 = 17 (Prime Number)
6 * (3) + 1 = 19 (Prime Number)
6 * (4) – 1 = 23 (Prime Number)
6 * (4) + 1 = 25 (Pseudo Prime Number)
我们可以使用4个方程式跟踪所有伪素数:
对于从y = 6 * x – 1产生的级数:
- y =(6 * d * x)+ d其中,x = {1,2,3,4,5,6,…}
- y =(6 * d * x)+(d * d)其中,x = {0,1,2,3,4,5,…}和d = {5,(5 + 6),(5 + 6) +6),(5 + 6 + 6 + 6),…,(5+(n-1)* 6)}
对于从y = 6 * x + 1产生的级数:
- y =(6 * d * x)+(d * d)其中,x = {0,1,2,3,…}
- y =(6 * d * x)+(d * d)– 2 * d其中,x = {1,2,3,4,…},d = {7,(7 + 6),(7 + 6) +6),…,(7 +(n – 1)* 6)}和n = {1、2、3、4、5,…}
Examples
Take d = 5 and x = 0 in equation 2,
y = 25 (Pseudo Prime Number)
Take d = 5 and x = 1 in equation 1,
y = 35 (Pseudo Prime Number)
Similarly, putting values in equation 3 and 4 we can track all Pseudo Prime Numbers.
如何在编程中实现?
We assume two bool type arrays of same size.
Say first one is array1, every element of which is initialized to 0.
And, second one is array2, every element of which is initialized to 1.
Now,
In array1, we initialize the specified indexes with 1, the index values are calculated using the equation y = (6 * x) ± 1.
And, in array2, we initialize the specified indexes with 0, the index values are calculated using 4 equations described above.
Now, run a loop from 0 to N and print the index value of array,
If array1[i] = 1 and array2[i] = 1 (i is a prime number).
下面是该方法的实现:
// C++ implementation of the approach
#include
using namespace std;
// Function to return the count of prime numbers <= n
int countPrimesUpto(int n)
{
// To store the count of prime numbers
int count = 0;
// To mark all the prime numbers according
// to the equation (y = 6*x -/+ 1)
// where x = 1, 2, 3, 4, 5, 6, 7, ...
bool arr1[n + 1];
// To mark all the Pseudo Prime Numbers
// using the four equations
// described in the approach
bool arr2[n + 1];
// Starting with >= 5
int d = 5;
// 2 and 3 are primes
arr1[2] = arr2[2] = 1;
arr1[3] = arr2[3] = 1;
// Initialize every element of arr1 with 0
memset(arr1, 0, sizeof(arr1));
// Initialize every element of arr2 with 1
memset(arr2, 1, sizeof(arr2));
// Update arr1[] to mark all the primes
while (d <= n) {
// For 5, (5 + 6), (5 + 6 + 6), ...
memset(arr1 + d, 1, (sizeof(arr1)) / (n + 1));
// For 7, (7 + 6), (7 + 6 + 6), ...
memset(arr1 + (d + 2), 1, (sizeof(arr1)) / (n + 1));
// Increase d by 6
d = d + 6;
}
// Update arr2[] to mark all pseudo primes
for (int i = 5; i * i <= n; i = i + 6) {
int j = 0;
// We will run while loop until we find all
// pseudo prime numbers <= n
while (1) {
int flag = 0;
// Equation 1
int temp1 = 6 * i * (j + 1) + i;
// Equation 2
int temp2 = ((6 * i * j) + i * i);
// Equation 3
int temp3 = ((6 * (i + 2) * j)
+ ((i + 2) * (i + 2)));
// Equation 4
int temp4 = ((6 * (i + 2) * (j + 1))
+ ((i + 2) * (i + 2)) - 2 * (i + 2));
// If obtained pseudo prime number <=n then its
// corresponding index in arr2 is set to 0
// Result of equation 1
if (temp1 <= n) {
arr2[temp1] = 0;
}
else {
flag++;
}
// Result of equation 2
if (temp2 <= n) {
arr2[temp2] = 0;
}
else {
flag++;
}
// Result of equation 3
if (temp3 <= n) {
arr2[temp3] = 0;
}
else {
flag++;
}
// Result of equation 4
if (temp4 <= n) {
arr2[temp4] = 0;
}
else {
flag++;
}
if (flag == 4) {
break;
}
j++;
}
}
// Include 2
if (n >= 2)
count++;
// Include 3
if (n >= 3)
count++;
// If arr1[i] = 1 && arr2[i] = 1 then i is prime number
// i.e. it is a prime which is not a pseudo prime
for (int p = 5; p <= n; p = p + 6) {
if (arr2[p] == 1 && arr1[p] == 1)
count++;
if (arr2[p + 2] == 1 && arr1[p + 2] == 1)
count++;
}
return count;
}
// Driver code
int main()
{
int n = 100;
cout << countPrimesUpto(n);
}
25