Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 我查找素数的代码不起作用。这里怎么了?_C - Fatal编程技术网

C 我查找素数的代码不起作用。这里怎么了?

C 我查找素数的代码不起作用。这里怎么了?,c,C,我试图找到高达1000的素数,但我只得到2和3 void main() { int i = 1, j, n = 1000; while (n != 0) { j = 2; i++; if (i % j != 0) { j++; } if (i == j) { printf("%d\n", i);

我试图找到高达1000的素数,但我只得到2和3

void main()
{
    int i = 1, j, n = 1000;

    while (n != 0)
    {
        j = 2;
        i++;
        if (i % j != 0)
        {
            j++;
        }

        if (i == j)
        {
            printf("%d\n", i);
            n--;
        }
    }
}

您的代码是用错误的逻辑实现的。它不会为每个
n
查找没有余数的第一个除数

要搜索素数,您必须对每个整数除数不小于给定数的数进行个性化处理,换句话说:如果给定数除以所有可能的除数(小于它),则生成一个余数(余数不是0),这就是素数

试着这样做:

#include <stdio.h>
#include <math.h>

/* Computes all primes from 1 to 1000 */
int main(void)
{
    int i,j,n=3; /* n=3 3 is the first odd number to test */

    /* 2 is the only even prime number */
    printf("%4d ",2);

    while(n<1000) {
        /* j=max usefull divisor */
        j=(int)sqrt(n);

        /* scanning divisors (i is the divisor)*/
        for(i=3;i<=j && (n%i);i+=2);

        /* if no divisor found print the number */
        if (i>j) {
            printf("%4d ",n);
        }

        /* Test the next odd number */
        n+=2;
    }
    puts("");
    return 0;
}

上面的代码(如“指示”@Chqrlie)避免了平方根,并计算了前1000个素数(正如您的代码所期望的那样)。

您的代码中存在问题:

  • 您应该
    #包括

  • main
    的原型不正确,它应该返回
    int

  • 您应该在循环外部初始化
    j
    ,并以稍微不同的顺序运行测试

  • 该代码的设计目的不是查找最多1000个素数,而是查找前1000个素数

以下是更正的版本:

#包括
//打印前1000个素数
int main(){
int i=2,j=2,n=1000;
而(n!=0){
如果(i%j==0){
如果(i==j){
printf(“%d\n”,i);
n--;
}
j=2;
i++;
}否则{
j++;
}
}
返回0;
}
但是请注意,您的算法令人困惑且效率低下:

  • 您可以在一个循环中组合实际应表示为两个嵌套循环的内容

  • 您可以测试小于或等于
    i
    的所有除数,而可以在
    j*j>i
    时停止,从而将时间复杂度从O(N2)降低到O(N1.5)

  • 您还可以使用特例
    2
    ,只测试奇数和除数,进一步减少另一个因子的除数

这里有一个替代方案:

#包括
//打印前1000个素数
int main(){
int i,j,n=1000;
如果(n>0){
printf(“%d\n”,2);
n--;
}
i=3;
而(n>0){
对于(j=3;;j+=2){
如果(j*j>i){
printf(“%d\n”,i);
n--;
打破
}
如果(i%j==0)
打破
}
i+=2;
}
返回0;
}

要获得提问的帮助,请阅读并研究我很好奇,如果这是你的第一个问题,你怎么知道提问很难?当
I==5时,在纸上或调试器中浏览你的代码。什么是
j
?也许您需要第二个循环?请作为问题重新表述。此答案不能解释原始代码中的错误。此答案表明代码需要两个循环,并且原始代码中的除法测试不正确。此答案不能解释原始代码中的错误。显示不同的代码虽然正确,但不是一种解释。它没有回答标题中提出的问题:这里出了什么问题?如果他阅读这里的代码,他可能会理解代码中的错误!逻辑性和实现性。@chqrlie,还有一个错误。。。如果发现底漆,则应减少cnt。然后旧算法打印的素数少于1000个。
#include <stdio.h>

/* Computes first 1000 primes */
int main(void)
{
    int i,n=3, cnt = 1000; /* n=3 3 is the first odd number to test */
    /* 2 is the only even prime number */
    printf("%4d ",2);
    cnt--; /* 2 was already written */

    while(cnt) {
        /* scanning divisors (i is the divisor)*/
        for(i=3;i*i<n && (n%i);i+=2);

        /* if no divisor found print the number */
        if (i*i>n) {
            printf("%4d ",n);
            cnt--;
        }

        /* Test the next odd number */
        n+=2;
    }

    puts("");

    return 0;
}