关于“C”中的Prime Generation - 我的代码出了什么问题? -

时间:2011-01-06 22:27:27

标签: c math computer-science

我是第三年不规范的CS学生,我刚刚意识到我必须开始编码。

我通过了我的编码类,其编程和编程方面没有很好的背景。

我正在尝试编写一个在给定的上限和下限之间生成素数的代码。不知道C井,强迫我写一个粗略的代码然后过去解决。我可以轻松地设置预期功能的逻辑,但我可能通过几种不同的方式创建错误的算法。

这里我分享了我的最后一个代码,我打算计算当一个数字给出余数为零时,它应该是self和1,所以count == 2;我的实现和我的解决方案生成风格有什么问题?我希望你能让我热衷于编程世界,我找不到足够的动力和勇气深入编程。

Stdio和Math.h被列入

int primegen(int down,int up)
{   
    int divisor,candidate,count=0,k;

    for(candidate=down;candidate<=up;candidate++)
    {
        for(divisor=1;divisor<=candidate;divisor++)
        {
            k=(candidate%divisor);
        }
        if (k==0) count++;
        if(count==2)
        {
            printf("%d\n", candidate);
            count=0;
        }
        else
        {
            continue;
        }
    }
}

int main()
{
    primegen(3,15);
    return 0;
}

6 个答案:

答案 0 :(得分:3)

您的candidate测试中包含1和candidate%divisor,两者都将返回0,因此您测试的每个数字都会显示为素数。

而不是:

for(divisor=1;divisor<=candidate;divisor++)

这样做:

for(divisor=2;divisor<candidate;divisor++)

更新

要列出的代码有太多问题,但不管怎样,这里有几个:

  • 您正在检查for循环外的candidate%divisor
  • 的结果
  • 当您检查k时,k始终为candidate%candidate或0
  • 你只能在除数循环后检查k一次
  • 在循环结束时不要continue,这是默认情况下发生的事情

看,这里有一些伪代码,用于最简单的实现。尝试找出代码与此不同的地方:

for candidate = down to up
  // assume the candidate is primt
  prime = true

  // check all divisors from 2 to the candidate - 1, inclusive
  for divisor = 2 to candidate - 1
    if candidate % divisor == 0
      // divisor is a factor of candidate
      // candidate isn't prime, so we can stop checking
      prime = false
      break
    end if
  next divisor

  // if prime is still true, we successfully tested every number from 2..candidate
  // and found no factors
  if prime
    print "candidate {candidate} is prime!"
  end if
next candidate

答案 1 :(得分:2)

  • 在你的内部循环中,你为所有除数计算candidate%divisor,但只有在循环结束后,你才能检查count是否应该递增。所以你只需要为每个候选人增加一次,以便检查最后一个除数。
  • 此外,您不会为外部循环中的每个候选项重置count。因此,当你想要为每个候选人单独计算时,你会计算所有候选人的已找到的除数。

答案 2 :(得分:1)

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

int primegen(unsigned int down,unsigned int up)
{   
int *ar;
int divisor,candidate,count=0,k;

for(candidate=up;candidate>=down;candidate--)
    {   count=0; 
        for(divisor=2;divisor<candidate;divisor++)
            {if (((candidate%divisor)==0)) count++; }
            if(count==0) {printf("%d\n",candidate); count=0;}

    }
}
int main()
{
primegen(3,15);
return 0;
}

最后我纠正了我的解决方案。主要问题是我没有在第二个for循环之前将计数分配给零。我改变了候选人的顺序(从大到小),我纠正了很少的语法错误。

感谢所有人的鼓励帮助和答案。 :)我很高兴完成这项工作,所以我可以通过其他算法和问题。

答案 3 :(得分:0)

要记住的一些提示

if(!(candidate & 0x01))
    // We know its even so we can stop

if(candidate == potential_factor)
    // We can stop

if(candidate % potential_factor == 0)
    // The potential factor IS a factor and we can stop

答案 4 :(得分:0)

为了清晰起见,有人重新格式化了原始提交的表单。在这样做时,他们修改了代码中的三个错误之一。

第一个错误是第二个声明后面没有括号。因此,循环体仅由第二个for语句后面的语句组成。通过阅读代码,很明显提问者想要在第二个循环语句之后重复执行所有内容。这不是发生的事情。

基本上,这个想法是:对于范围内的每个数字,尝试1和候选者之间的所有数字。计算除以它的数量。看看是否有2个。这是一个正确的算法,并且说不分2的答案是错误的。

然而,实现是这样做的:对于范围内的每个数字,将候选者除以1和候选者之间的每个数字。然后,一旦你完成了所有的分工,检查最后一个是否出来,如果是,则在计数中加1。所以,正在发生的事情是你实际上只是在查看candidate % candidate == 0它是否总是这样做。

第二个错误是,计数只有在达到2时才会重置。因此,正在发生的事情是,对于任何输入,代码将返回每隔一个数字。对于每位候选人,count++只发生一次。所以它达到2并且每隔一段时间重置一次。

第三个错误是,一旦最内层循环被修复,那么继续将做错事,因为它只会继续最内层循环。

答案 5 :(得分:0)

我知道您的代码仅用于教育目的,但您应该考虑使用Sieve of Eratosthenes,因为它可能是您问题的最快算法。它基本上做的是:

  1. 首先考虑所有数字素数。
  2. 从2开始,您考虑素数非素数的所有倍数。
  3. 转到下一个素数,并将其全部变为非素数。
  4. 我认为通过阅读本文可以更好地理解算法: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

    至于实现,只需使用一个数组,其所有元素都设置为零,并将元素从素数设置为素数为一。

    希望这有帮助!