You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求修复:埃拉托斯特尼筛法求100以内素数程序异常问题

问题分析与修复

你的代码存在两个核心问题导致j无法超过2:

1. 外层循环终止条件错误

原代码外层循环使用j <= num[99]作为终止条件,但num[99]初始值是100,当j=2执行内层循环时,n=50会计算出j*n=100,此时num[99]会被设为0。后续j自增到3时,3 <= 0不成立,循环直接终止,导致j永远无法处理3及以上的数。

2. 内层循环逻辑冗余且存在潜在风险

原代码内层循环用n从j开始遍历,计算j*n标记非素数,但j*j之前的倍数已经被更小的素数标记过(比如j=3时,6已经被j=2标记),重复标记会浪费性能;同时如果j过大,j*n可能超过100,导致数组越界(虽然100以内不会触发,但逻辑不严谨)。


修复后的代码

#include <stdio.h>

int main()
{
    int i, j, num[100], sum = 0;
    // 初始化数组:num[i] = i+1,对应1到100的数
    for (i = 0; i < 100; i++)
        num[i] = i + 1;

    // 外层循环:遍历2到10,更高效的终止条件是j*j <=100(sqrt(100)=10)
    for (j = 2; j * j <= 100; j++)
    {
        // 如果当前j已经被标记为非素数,跳过无效处理
        if (num[j-1] == 0)
            continue;
        // 内层循环:从j的平方开始标记倍数,避免重复处理已标记的数
        for (int k = j * j; k <= 100; k += j)
        {
            num[k-1] = 0;
        }
    }

    // 求和:累加2到100中未被标记的素数(跳过了num[0]的1)
    for (i = 1; i < 100; i++)
    {
        if (num[i] != 0)
            sum += num[i];
    }
    printf("%d\n", sum);
    return 0;
}

额外说明

  • 终止条件改为j*j <=100:大于sqrt(100)的数如果没被标记,必然是素数,无需再处理其倍数,大幅提升效率。
  • 内层循环从j*j开始:避免重复标记已被更小素数处理过的倍数,减少冗余操作。
  • 增加if(num[j-1]==0) continue:跳过已被标记为非素数的j,避免无效遍历。

内容的提问来源于stack exchange,提问作者Vinayak Deshmukh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 16:30:23