【问题标题】:Displaying primes from 2-10,000 in C在 C 中显示 2-10,000 的素数
【发布时间】:2013-11-08 07:59:18
【问题描述】:

我正在努力解决我的教授建议我尝试的这个(可选)问题。基本上,我的任务是编写一个程序,使用我自己的用户定义函数来显示从 2 到 10,000 的所有素数,以确定素数。这听起来很简单,但我在调试我的程序时遇到了很大的困难。由于某种原因,我的代码在结束前只显示 2 和 3。

#include<stdio.h>
//function declaration
int prime(int);
//main body
int main(void)
{
    int x=2, y;
    for (x=2;x<=30;x++)
    {
        y=prime(x);
        if (y!=0)
            printf("%d\n", x);
    }
    getchar();
    return(0);
}
//function definition
int prime(int x)
{
    int y;
    for (y=2; y<=(int)sqrt(x); ++y)
    {
        if (x%y==0)
           return 0;
    }
    if (y==(int)sqrt(x))
       return 1;
}

如果 x 是素数,我的素数检查函数似乎返回一个随机大数 (2686xxx),而不是返回 1,但这不应该成为问题,因为所有素数都返回 0。如果我运行类似:

if (y==0)
    printf("%d\n", x);

我看到了所有非素数的列表。如果我运行类似:

printf("%d    %d\n", x, y);

我看到了从 2 到 10,000 的所有整数的列表以及我的素数检查函数的结果(0 表示非素数,2686xxx 表示素数)。

为什么相反的 (y!=0) 不显示素数列表?是什么导致我的代码在显示 2 和 3 后停止?为什么我的素数函数返回一个奇怪的整数而不是 1?最后,我仍然是一个初学者,但我如何才能写出更好的代码呢?我认为我没有违反任何公认的标准做法,但我怎样才能使我的代码更干净或更高效?

提前感谢您的帮助!

【问题讨论】:

  • 如果 x 为 3,请仔细检查 prime 函数的作用。您应该能够明白为什么它返回一个无意义的值。 (提示:2 大于 (int)sqrt(3) 对吧?)
  • 确保函数的所有路径都有返回语句。你的prime 函数没有。
  • 相关:考虑构建一个Sieve of Eratosthenes,并在完成后取出所有素数。您需要一组标志、一个嵌套循环和一些简单的数学运算。查看链接的文章以了解有关算法的详细信息。

标签: c primes


【解决方案1】:

如果y==(int)sqrt(x),您的循环继续。所以当它结束时,它们是不相等的。你想要的是:

if (y>=(int)sqrt(x))
   return 1;

但这根本不需要。只需return 1; 就足够了。如果数字不是素数,您已经返回零。

如果你只想要一个返回语句:

int prime(int x)
{
    bool isPrime = true;
    int y;
    for (y=2; y<=(int)sqrt(x); ++y)
    {
        if (x%y==0)
        {
            isPrime = false;
            break;
        }
    }
    return isPrime;
}

【讨论】:

  • 感谢您的帮助。让我快速检查一下我是否理解我的错误。完成循环后, y==(int)sqrt(x)+1 所以我最初写的不会返回任何东西。但是,完全没有必要编写 if 语句,因为所有非素数都已经返回 0。函数在返回某些内容后中断,对吗?我最初担心删除 if 条件会使每个整数都返回 1,但似乎并非如此。
  • @muri return 语句不仅可以让你返回一些东西,它还可以返回给调用者。我更新了我的答案,以展示如何只用一个 return 语句而不需要额外的测试来做到这一点。
【解决方案2】:

不要使用 sqrt() 函数。在数学中,如果你有'x = sqrt(y)'。如果你把两边都平方,你会得到类似'x * x = y'的东西。 c 中的这个表达式比 sqrt 函数快得多。因此,而不是这样做:

y <= (int)sqrt(x)

你有没有像这样的循环保护:

y * y <= x

这是您的问题的运行示例:

Primes 2 -> 10000

【讨论】:

    【解决方案3】:

    在你的素数函数结束时只返回 1。如果它不是素数,它会更早地返回 0。对吧?

    事实上,您已经创建了一个有时根本不返回任何内容的函数。这意味着它返回寄存器中发生的任何随机值。

    【讨论】:

      【解决方案4】:

      您可以使用 sieve of eratosthenes 或 sieve of atkin 标记数组中的所有素数,然后显示素数。尽管会产生一些空间复杂性,但它会节省时间。

      例如,如果您想显示从 1 到 10 的素数

      离开 1。它不是素数。它既不是素数也不是合数。

      所以从 2 开始。

      考虑这个大小为 10 = 2 3 4 5 6 7 8 9 10 的数组

      从 2 开始遍历。如果一个元素未突出显示,则突出显示其所有倍数。

      即 2 突出显示其倍数 4 6 8 10

      ==> 2 3 4 5 6 7 8 9 10

      对于 3 做同样的事情

      ==> 2 3 4 5 6 7 8 9 10

      然后对其余的编号进行操作,即 5 和 10(这里 7 没有多个)

      最后打印未突出显示的元素。 2,3,5,7。

      对任何其他范围重复此过程。

      【讨论】:

        【解决方案5】:

        由于您对编写质数的计算机程序感兴趣,也许您想把这篇论文变成一个计算机程序。它处理素数,类似于您试图在 C 中创建的筛子。

        https://graviticpropulsion.files.wordpress.com/2015/04/prime-number-theory.pdf

        我不确定它是更快还是更少的内存密集型,但我很好奇自己能找到多高的质数,然后才变得对计算机来说过于密集。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-11-30
          • 2023-04-06
          • 1970-01-01
          • 2016-01-23
          • 1970-01-01
          • 2017-12-06
          • 2018-01-12
          • 1970-01-01
          相关资源
          最近更新 更多