生成素数的最佳方法是什么?

时间:2015-07-14 15:05:10

标签: c algorithm

我正在做Kochan的C编程练习;就在最初阶段,第5章。

这是任务:

计划5.10有几个效率低下。检查偶数会导致效率低下。             因为很明显,任何大于2的偶数都不能成为素数,程序可以简单地跳过所有偶数作为可能的素数和可能的除数。内循环也是低效的,因为p的值总是除以d的所有值,从2到。通过在for循环的条件中添加is_prime值的测试,可以避免这种低效率。以这种方式,只要没有找到除数并且d的值小于p,就可以将for循环设置为继续。修改程序5.10以包含这两个更改。

这是程序5.10

    // generate a table of prime numbers
    #include <stdio.h>

    int main (void)
    {
        int p, d;
        _Bool is_prime;

        for (p = 2; p <= 50; ++p)
        {
            is_prime = 1;

            for (d = 2; d < p; ++d)
                if (p % d == 0)
                    is_prime = 0;

                if (is_prime)          // or if (is_prime != 0); same
                    printf ("%i ", p);
        }

        printf ("\n");
        return 0;
    }

这是我想写的两个选项,但两者都有 打印出空白区域;没有数字生成。 第一个可能代表一种完全错误的方法,     但是我不明白为什么第二个不会起作用。

选项1:

 // generate a table of prime numbers
#include <stdio.h>
#include <stdbool.h>

int main (void)
{
    int p, d;
    bool is_prime;

    /* start from p=2, do until p is less than 50,

     and skip all even numbers */

    for (p = 2; (p < 50) && (p % 2 != 0); ++p)

    {
        is_prime =1;

        /* the inner for loop says: start from d = 2; do until
         d is less than p, and also test if p is prime or not by
         dividing p by d */

        for (d = 2; d < p (p % d != 0 ? is_prime : !is_prime); ++d)

             printf ("%i ", p);
    }

    printf ("\n");
    return 0;
}

选项2:

// generate a table of prime numbers
#include <stdio.h>
#include <stdbool.h>

int main (void)
{
    int p, d;
    bool is_prime;

    /* start from p=2, do until p is less than 50,

     and skip all even numbers */

    for (p = 2; (p < 50) && (p % 2 != 0); ++p)

    {
        is_prime =1;

        /* the inner for loop says: start from d = 2; do until
         d is less than p, and also test if p is prime or not by
         dividing p by d */

        for (d = 2; (d < p) && (p % d != 0); ++d )
            /* this inner loop was supposed to print the number if
             it is not divided by d */

            printf ("%i ", p);
    }

    printf ("\n");
    return 0;
}

我很感激你的帮助!我是编程新手。

谢谢!

3 个答案:

答案 0 :(得分:0)

嗯....

#include <stdio.h>
#include <stdbool.h>
int main(void) {
  unsigned int d = 0;
  unsigned int p = 0;
  bool is_prime = false;
  // We know 2 is prime
  printf( "%u ", 2 );
  for (p = 3; p < 50; p += 2 ) {
    // Skipped even numbers
    is_prime = true;
    // Since 2 is prime and we got rid of even numbers
    // We can just check odd divisors by starting with 3 and incrementing by 2
    for (d = 3; d * d < p && is_prime == true; d += 2) {
      // If we have a divisor, it's not prime
      if (p % d == 0) {
        is_prime = false;
      }
    }
    // This was outside the loop in the original program
    if (is_prime) {
      printf("%u ", p);
    }
  }
  return 0;
}

首先,我们知道2是我们唯一的素数,所以为了简化,我们继续打印并从3开始。由于没有其他偶数是素数,我们每个循环增加2(记住 - 一个for循环当条件为假时停止,因此我们不能将p % 2 != 0称为循环条件。我们将is_prime设置为true然后测试所有奇数除数。如果找到除数,则数字不是素数,我们停止测试;否则,这个数字是素数。再说一次,因为2是唯一的素数,我们甚至可以跳过除数。最后,如果我们超过该数字的平方根,那么该数字将保证为素数。

答案 1 :(得分:0)

您的代码中的问题是您的第一个for-loop警卫。循环我引用:

for (p = 2; (p < 50) && (p % 2 != 0); ++p)

如果仔细观察后卫,你会发现它会开始变错。使用初始值p = 2,可以获得循环保护的扩展

(2 < 50) && (2 % 2 != 0) == true && (0 != 0) == true && false == false 因此,因为你的循环保护最初是假的,所以循环永远不会运行。

如果你想要解决方案,似乎这个问题的另外两个答案提供了一些风格上比你所写的更好的东西(风格在编程中很重要)和正确。

答案 2 :(得分:-2)

\Z