如何编写仅用循环查找n以内所有sexy prime对的C语言程序
代码问题分析
- flag变量未重置:你在代码开头初始化了
flag=0,但每次判断新的prime2是否为素数前没有把flag重置为0,只要有一次prime2被判定为非素数,flag就会一直保持≥1的状态,后续所有判断都无法满足flag == 0的输出条件 - prime2素数判断逻辑错误:判断
prime2是否为素数的循环从k=3开始,遗漏了对因数2的判断,而且循环终止条件写的是k <= prime2,任何数都能被自身整除,所以不管prime2是不是素数,循环走到k=prime2时都会触发prime2 % k ==0的逻辑,flag一定会被加1,永远不会满足输出条件 - 素数判断效率低:不管是判断i还是
prime2是否为素数,循环都跑到数值本身,其实只需要跑到数值的平方根即可,因为如果一个数有大于其平方根的因数,必然存在对应的小于平方根的因数,提前终止循环能大幅减少运算量
仅使用循环的优化技巧
- 每次判断单个数值是否为素数前,先重置对应的标记变量,避免历史结果干扰当前判断
- 素数判断循环的终止条件改为
j*j <= 目标数,不需要遍历到目标数本身,能减少70%以上的循环次数 - 除了2之外所有素数都是奇数,你可以直接从i=3开始遍历,步长设为2跳过所有偶数,直接减少一半的遍历量
- 可以提前用数组实现埃氏筛,先一次性标记出所有≤n+6的数是否为素数,后续判断只需要取数组值即可,不需要每次都重新跑素数判断循环,适合n较大的场景
修改后可正常运行的代码
#include <stdio.h> int main() { int i, j, n, k, prime2; scanf("%d", &n); for (i = 2; i <= n; i++){ // 判断i是否为素数 int is_prime = 1; for (j = 2; j*j <= i; j++){ if (i % j == 0) { is_prime = 0; break; } } if (is_prime == 1){ prime2 = i + 6; // 判断prime2是否为素数 int is_prime2 = 1; for (k = 2; k*k <= prime2; k++){ if (prime2 % k == 0){ is_prime2 = 0; break; } } if (is_prime2 == 1){ printf("(%d, %d)\n", i, prime2); } } } return 0; }
内容的提问来源于stack exchange,提问作者sggus
相关产品推荐
相关产品推荐

