题目:判断一个数字是否为质数
程序分析
要判断一个数字是否为质数,需要检查该数字是否能被除了1和它本身之外的其他整数整除。如果能被整除,那么它不是质数。否则,它是质数。
方法1:简单遍历法
解题思路
从2开始遍历到该数字的平方根,检查是否能整除该数字。
实现代码
#include <stdio.h>
#include <math.h>
int is_prime_simple(int num) {
if (num < 2)
return 0;
int sqrt_num = (int)sqrt(num);
for (int i = 2; i <= sqrt_num; i++) {
if (num % i == 0)
return 0;
}
return 1;
}
优缺点
- 优点:
- 实现简单,容易理解。
- 缺点:
- 效率较低,时间复杂度为O(√n),可能不适用于大数判断。
方法2:优化遍历法
解题思路
在简单遍历法的基础上,可以进行一些优化。只需要遍历到该数字的平方根,同时每次遍历加2(因为偶数除了2都不是质数)。
实现代码
#include <stdio.h>
#include <math.h>
int is_prime_optimized(int num) {
if (num < 2)
return 0;
if (num == 2)
return 1;
if (num % 2 == 0)
return 0;
int sqrt_num = (int)sqrt(num);
for (int i = 3; i <= sqrt_num; i += 2) {
if (num % i == 0)
return 0;
}
return 1;
}
优缺点
- 优点:
- 比简单遍历法效率更高,因为避免了偶数的判断。
- 缺点:
- 仍然有一定的时间复杂度,不适用于极大数判断。
方法3:埃拉托斯特尼筛法(Sieve of Eratosthenes)
解题思路
该方法利用了质数的特性:所有的非质数都可以分解为质数的乘积。从小到大逐步筛选掉非质数,直到剩下的数字即为质数。
实现代码
#include <stdio.h>
#include <stdlib.h>
int is_prime_eratosthenes(int num) {
if (num < 2)
return 0;
// Create an array to mark if a number is prime
int *prime_flags = (int *)malloc((num + 1) * sizeof(int));
if (prime_flags == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
// Initialize the array
for (int i = 0; i <= num; i++) {
prime_flags[i] = 1; // Assume all numbers are prime initially
}
prime_flags[0] = prime_flags[1] = 0; // 0 and 1 are not prime
// Apply Sieve of Eratosthenes algorithm
for (int i = 2; i * i <= num; i++) {
if (prime_flags[i]) {
for (int j = i * i; j <= num; j += i) {
prime_flags[j] = 0; // Mark multiples of prime numbers as non-prime
}
}
}
int is_prime = prime_flags[num];
free(prime_flags);
return is_prime;
}
优缺点
- 优点:
- 效率较高,时间复杂度为O(n log log n)。
- 缺点:
- 需要额外的空间来存储标记,空间复杂度较高。
总结与推荐
- 方法1(简单遍历法)是最简单直接的实现,但效率较低,不适用于大数判断。
- 方法2(优化遍历法)在简单遍历法的基础上进行了优化,效率较高,但仍然有一定的时间复杂度。
- 方法3(埃拉托斯特尼筛法)效率最高,适用于较大数判断,但需要额外的空间。
推荐使用方法3(埃拉托斯特尼筛法)作为最优方法,尤其对于大数判断,它能提供较高的效率。如果对空间复杂度有较高要求,可以根据具体情况选择方法2(优化遍历法)。方法1(简单遍历法)在效率上不如方法2和方法3,不推荐在实际应用中使用。