查找素数的程序打印出两个

时间:2013-10-09 19:30:30

标签: c

我对编程很新,我想尝试编写一个程序来查找一系列数字中的素数。当我通过编译器运行这个程序时,我没有得到任何错误,但当我尝试实际运行该程序时,它说只有2,这是不正确的。我认为它应该是大约168.如果你能帮我指出我的错误,我会很感激。提前致谢!

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

void primeFinder(void);

int main(void)
{
    printf("Prime numbers from 1 to 1000:\n\n");
    primeFinder();

    return 0;
}


void primeFinder(void)
{
    int i;
    int j;
    int k;
    int n_primes = 0;

    //i is the number to be tested:
    for ( i = 2 ; i <= 1000 ; i++ )
    {
        //i must be divided by j, that goes from 2 to i - 1 [(i - 2) divisions]:
        for ( j = 2, k = 0 ; j <= sqrt(i) ; j++ )
        {
            //i is not prime, whatever is the value of j:
            if ( i % j == 0 )
            {
                //If remainder is 0, there is no need to test that i anymore:
                break;
            }
            else
            {
                k++;
            }

        } //End of inner for
            //i is prime:
        if ( k == i - 2 )
        {
            printf("%d\t", i);
            n_primes++;
        }
    } //End of outer for
    printf("\n\nIt was found %d prime(s) in the inverval considered.\n", n_primes);
}

8 个答案:

答案 0 :(得分:1)

我给初学者程序员提供的一个建议是:“认为模块化!”换句话说,训练自己分裂和征服;我怎样才能将问题分解为基本组成部分?

您的计划的一个好框架如下:

#include <stdio.h>

typedef int BOOL;

#define TRUE 1
#define FALSE 0    

BOOL is_prime(int number);

int main()
{
    printf("Prime numbers between 1 and 1000:\n");

    int i;
    for (i = 1; i <= 1000; ++i)
    {
        if (is_prime(i))
        {
            printf("%d\n", i);
        }
    }

    return 0;
}

// ...

这是因为,稍后,如果您需要确定数字是否为素数,您只需复制并粘贴现有的实现即可。

以下是is_prime的一个实现,我经常使用并完成相当好的工作:

BOOL is_prime(int number)
{
    // If the number is less than two, then it is not prime.
    if (number < 2)
    {
        return FALSE;
    }

    // If the number is two, then it is prime.
    if (number == 2)
    {
        return TRUE;
    }

    // If the number is even, then it is not prime.
    if (number % 2 == 0)
    {
        return FALSE;
    }

    // Try and divide the number by all odd numbers
    // less than or equal to its square root. If
    // we can, then it is not prime. Otherwise, it is.
    int i;
    for (i = 3; i * i <= number; i += 2)
    {
        if (number % i == 0)
        {
            return FALSE;
        }
    }
    return TRUE;
}

答案 1 :(得分:0)

if ( k == i - 2 )此检查错误,前一个块仅针对sqrt(i) - 2个数字进行循环。您需要查看sqrt(i) -2

答案 2 :(得分:0)

j到达i的平方根后退出内循环。因此k不计算不分i的完整数字。

答案 3 :(得分:0)

为什么要跟踪k?只需设置一个标志,告诉您数字是否为素数:

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

int num_primes(int limit) {
    int i;
    int j;
    int n_primes = 0;
    bool is_prime; /* note stdbool.h in the includes */

    for (i = 2; i <= limit; i++) {
        is_prime = true;
        for (j = 2; j <= sqrt(i); j++) {
            if (i % j == 0) {
                is_prime = false;
                break;
            }
        }
        /* This could be written as `if (is_prime) n_primes++;` */
        n_primes += is_prime;
    }
    return n_primes;
}

答案 4 :(得分:0)

这是你的支票。你这样做的方式有点奇怪。我认为更简单的方法是创建一个标志并将其设置为true。所以你假设这个数字是素数。正如您所经历的那样,如果您发现该数字不是素数,请将该标志设置为false。之后,检查标志是否仍为真,如果是,则打印结果。这就是我所说的:

  int i;
int j;
int k;
int n_primes = 0;
bool flag;

//i is the number to be tested:
for ( i = 2 ; i <= 1000 ; i++ )
{
    //Assume it's prime
    flag=true;
    //i must be divided by j, that goes from 2 to i - 1 [(i - 2) divisions]:
    for ( j = 2 ; j <= sqrt((double)i) ; j++ )
    {
        //i is not prime, whatever is the value of j:
        if ( i % j == 0 )
        {
            //If remainder is 0, there is no need to test that i anymore:
            flag=false;
            break;
        }
    } //End of inner for
        //i is prime:
    if ( flag==true )
    {
        printf("%d\t", i);
        n_primes++;
    }
} //End of outer for
printf("\n\nIt was found %d prime(s) in the inverval considered.\n", n_primes);

答案 5 :(得分:0)

好像你在中间更改了算法,即不检查最高i-1的divisiors(这很浪费),你测试到sqrt(i)

问题是您只更改了循环条件,但没有更新以下条件:

if ( k == i - 2 )

您有两个选择:

  1. 回滚到朴素算法并将循环条件更改为:

    for( j = 2, k = 0 ; j <= i-1 ; j++ )

  2. 更改您的程序逻辑,这样您只需要知道1 以外的除数是否存在,无论这些除数的数量是多少。

答案 6 :(得分:0)

如果数字是素数,k将增加到sqrt(i)的值。正如你所见,if条件并不总是正确的。

而不是使用计数器,你只需要一个标志来知道它是否是素数。也许是这样的:

    //i must be divided by j, that goes from 2 to i - 1 [(i - 2) divisions]:
    for ( j = 2, k = 1 ; j <= sqrt(i) ; j++ )
    {
        //i is not prime, whatever is the value of j:
        if ( i % j == 0 )
        {
            //If remainder is 0, there is no need to test that i anymore:
            k = 0;
            break;
        }
    } //End of inner for
    if (k) // i is prime
    {
    ...

答案 7 :(得分:0)

问题在于

if ( k == i - 2 )

i的值是固定的,k是变化的。因此,以下行仅针对i = 2和3执行。因此,您将得到答案2.

if ( k == i - 2 )
{
      printf("%d\t", i);
      n_primes++;
}

您可能会发现以下代码非常有用:

#include<stdio.h>
#include<math.h>
#define TRUE 1
#define FALSE 0
int isPrimeNumber(int num)
{
    int i=2;
    int len=sqrt(num);
    if(num<2) return FALSE;
    while(i<=len)
    {
        if(num%i==0)
        {
            return FALSE;
        }
        i++;
    }

    return TRUE;
}

int countPrimeNumbersInRange(int start, int end)
{
    int count=0;
    while(start<=end)
    {
        if(isPrimeNumber(start))
        {
            printf("%d\t",start);
            count++;
        }
        start++;
    }
    return count;
}

int main()
{
    printf("\n\nIt was found %d prime(s) in the inverval considered.\n", countPrimeNumbersInRange(1, 1000));
    return 0;
}