使用数组打印素数
Printing prime numbers using arrays
这是打印质数的代码。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
int p;
int i;
int primes[50] = { 0 };
int primeIndex = 2;
bool isPrime;
// hardcode prime numbers
primes[0] = 2;
primes[1] = 3;
for (p = 5; p <= 100; p = p + 2) {
isPrime = true;
for (i = 1; isPrime && p / primes[i] >= primes[i]; ++i)
if (p % primes[i] == 0)
isPrime = false;
if (isPrime == true) {
primes[primeIndex] = p;
++primeIndex;
}
}
for (i = 0; i < primeIndex; ++i)
printf ("%i ", primes[i]);
printf("\n");
return 0;
}
我不明白这段代码中的一些事情:
内部for循环的条件如何工作以及isPrime
变量的用途是什么?
代码正确计算并打印所有小于或等于 100 的素数。
Why is it necessary to hard-code 2 prime numbers (2 and 3)?
2
是一个特例:它是唯一的偶素数。 2
被硬编码为第一个素数,因此外循环仅测试奇数。
3
是硬编码的,因此外循环可以依赖数组内容作为其停止条件 p / primes[i] >= primes[i]
。数组中需要至少有一个奇质数,以避免对数组索引进行额外的测试,例如i < primeIndex
.
正如 chux 评论的那样,内部循环可以从索引 i = 0
开始,然后只需要将 2
硬编码到数组中。筛选过程的效率会稍微低一些,因为所有数字都将被不必要地测试为可被 2 整除,可以跳过,因为所有测试的数字都是奇数。
What is the use of boolean expression in the first for
loop?
第一个 for
循环中的条件测试是 p <= 100
。该程序枚举小于或等于 100
的素数。 primes
数组的长度为 50
,足以满足此范围。如果范围大得多,则需要扩展数组大小。
布尔变量isPrime
用于存储素性测试的结果。它被初始化为 true
,当且仅当在内部循环中找到质因数时,它才会被重置为 false
。
在内部循环之后测试变量以检查 p
是否应该附加到素数列表。
第二个 for
循环 isPrime && p / primes[i] >= primes[i]
中的条件是一个优化:它允许循环在找到除数后立即停止。该测试可以简化为 p / primes[i] >= primes[i]
并且循环将继续测试素数直到 p
的平方根。在找到除数时添加 break
语句是提前停止循环以提高效率的替代方法。
Can someone explain me how the inner for loop works?
内部循环对质数除数进行迭代,直到发现一个余数为 0 (p % primes[i] == 0
) 或直到除数大于 p
的平方根 (p / primes[i] >= primes[i]
).
注意数组primes
不需要初始化。
这是一个简化版本:
#include <stdio.h>
#include <stdbool.h>
int main() {
int primes[50];
int i, p, primeIndex;
// hardcode 2 prime numbers
primes[0] = 2;
primes[1] = 3;
primeIndex = 2;
// enumerate odd numbers from 5 to 100
for (p = 5; p <= 100; p = p + 2) {
// use a boolean variable that will be set to false if p is composite
bool isPrime = true;
// test all odd prime divisors up to the square root of p
for (i = 1; p / primes[i] >= primes[i]; ++i) {
if (p % primes[i] == 0) {
isPrime = false;
break;
}
}
// if p is prime, add it to the array.
if (isPrime) {
primes[primeIndex++] = p;
}
}
for (i = 0; i < primeIndex; ++i)
printf("%i ", primes[i]);
printf("\n");
return 0;
}
这是一个使用函数的更简单的版本:
#include <stdio.h>
#include <stdbool.h>
// test if an odd number greater than 3 is a prime
bool isOddPrime(int p, const int *primes) {
for (int i = 1; p / primes[i] >= primes[i]; ++i) {
if (p % primes[i] == 0)
return false;
}
return true;
}
int main() {
int primes[50] = { 2, 3 }; // hardcode 2 prime numbers
int primeIndex = 2;
for (int p = 5; p <= 100; p = p + 2) {
if (isOddPrime(p))
primes[primeIndex++] = p;
}
for (i = 0; i < primeIndex; ++i)
printf("%i ", primes[i]);
printf("\n");
return 0;
}
这是打印质数的代码。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
int p;
int i;
int primes[50] = { 0 };
int primeIndex = 2;
bool isPrime;
// hardcode prime numbers
primes[0] = 2;
primes[1] = 3;
for (p = 5; p <= 100; p = p + 2) {
isPrime = true;
for (i = 1; isPrime && p / primes[i] >= primes[i]; ++i)
if (p % primes[i] == 0)
isPrime = false;
if (isPrime == true) {
primes[primeIndex] = p;
++primeIndex;
}
}
for (i = 0; i < primeIndex; ++i)
printf ("%i ", primes[i]);
printf("\n");
return 0;
}
我不明白这段代码中的一些事情:
内部for循环的条件如何工作以及isPrime
变量的用途是什么?
代码正确计算并打印所有小于或等于 100 的素数。
Why is it necessary to hard-code 2 prime numbers (2 and 3)?
2
是一个特例:它是唯一的偶素数。 2
被硬编码为第一个素数,因此外循环仅测试奇数。
3
是硬编码的,因此外循环可以依赖数组内容作为其停止条件 p / primes[i] >= primes[i]
。数组中需要至少有一个奇质数,以避免对数组索引进行额外的测试,例如i < primeIndex
.
正如 chux 评论的那样,内部循环可以从索引 i = 0
开始,然后只需要将 2
硬编码到数组中。筛选过程的效率会稍微低一些,因为所有数字都将被不必要地测试为可被 2 整除,可以跳过,因为所有测试的数字都是奇数。
What is the use of boolean expression in the first
for
loop?
第一个 for
循环中的条件测试是 p <= 100
。该程序枚举小于或等于 100
的素数。 primes
数组的长度为 50
,足以满足此范围。如果范围大得多,则需要扩展数组大小。
布尔变量isPrime
用于存储素性测试的结果。它被初始化为 true
,当且仅当在内部循环中找到质因数时,它才会被重置为 false
。
在内部循环之后测试变量以检查 p
是否应该附加到素数列表。
第二个 for
循环 isPrime && p / primes[i] >= primes[i]
中的条件是一个优化:它允许循环在找到除数后立即停止。该测试可以简化为 p / primes[i] >= primes[i]
并且循环将继续测试素数直到 p
的平方根。在找到除数时添加 break
语句是提前停止循环以提高效率的替代方法。
Can someone explain me how the inner for loop works?
内部循环对质数除数进行迭代,直到发现一个余数为 0 (p % primes[i] == 0
) 或直到除数大于 p
的平方根 (p / primes[i] >= primes[i]
).
注意数组primes
不需要初始化。
这是一个简化版本:
#include <stdio.h>
#include <stdbool.h>
int main() {
int primes[50];
int i, p, primeIndex;
// hardcode 2 prime numbers
primes[0] = 2;
primes[1] = 3;
primeIndex = 2;
// enumerate odd numbers from 5 to 100
for (p = 5; p <= 100; p = p + 2) {
// use a boolean variable that will be set to false if p is composite
bool isPrime = true;
// test all odd prime divisors up to the square root of p
for (i = 1; p / primes[i] >= primes[i]; ++i) {
if (p % primes[i] == 0) {
isPrime = false;
break;
}
}
// if p is prime, add it to the array.
if (isPrime) {
primes[primeIndex++] = p;
}
}
for (i = 0; i < primeIndex; ++i)
printf("%i ", primes[i]);
printf("\n");
return 0;
}
这是一个使用函数的更简单的版本:
#include <stdio.h>
#include <stdbool.h>
// test if an odd number greater than 3 is a prime
bool isOddPrime(int p, const int *primes) {
for (int i = 1; p / primes[i] >= primes[i]; ++i) {
if (p % primes[i] == 0)
return false;
}
return true;
}
int main() {
int primes[50] = { 2, 3 }; // hardcode 2 prime numbers
int primeIndex = 2;
for (int p = 5; p <= 100; p = p + 2) {
if (isOddPrime(p))
primes[primeIndex++] = p;
}
for (i = 0; i < primeIndex; ++i)
printf("%i ", primes[i]);
printf("\n");
return 0;
}