关于“C”中的素数生成- 我的代码有什么问题吗? -

发布于 2024-10-10 22:16:42 字数 846 浏览 6 评论 0原文

我是一名非正规计算机专业三年级学生,我刚刚意识到我必须开始编码。

我以较低的成绩通过了编码课程,因此我在编码和编程方面没有良好的背景。

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

在这里我分享我的最后一个代码,我打算计算当一个数字给出余数 Zero 时,它应该是 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;
}

I'm a third year irregular CS student and ,i just realized that i have to start coding.

I passed my coding classes with lower bound grades so that i haven't a good background in coding&programming.

I'm trying to write a code that generates prime numbers between given upper and lower bounds. Not knowing C well, enforce me to write a rough code then go over it to solve. I can easily set up the logic for intended function but i probably create a wrong algorithm through several different ways.

Here I share my last code, i intend to calculate that when a number gives remainder Zero , it should be it self and 1 , so that count==2; What is wrong with my implementation and with my solution generating style? I hope you will warm me up to programming world, i couldn't find enough motivation and courage to get deep into programming.

Stdio and Math.h is İncluded

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一枫情书 2024-10-17 22:16:42

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

而不是这样做:

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

执行此操作:

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

update

您的代码有太多问题无法列出,但无论如何,这里有几个:

  • for 循环外部检查 candidate%divisor 的结果
  • 您正在通过 当你检查k时,k总是candidate%candidate,或者0
  • 你只检查一次k,之后除数循环
  • 在循环结束时不会继续,这就是默认情况下发生的情况。

看,这里是一些最简单的实现的伪代码。尝试找出您的代码与此的偏差:

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

You're including 1 and the candidate in your candidate%divisor tests, both of which will always return 0, so every number you test will appear prime.

Instead of this:

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

do this:

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

update

There are too many things wrong with your code to list, but here are a couple anyways:

  • you're checking the result of candidate%divisor outside the for loop
  • by the time you check k, k is always candidate%candidate, or 0
  • you only ever check k once, after the divisor loop
  • don't continue at the end of your loop, that's what happens by default

Look, here is some pseudo-code for the simplest possible implementation. Try to find where your code deviates from this:

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
南渊 2024-10-17 22:16:42
  • 在内部循环中,您计算​​所有除数的 candidate%divisor ,但只有在循环完成后,您才检查 count 是否应该增加。因此,对于检查的最后一个除数,每个候选者只需增加一次。
  • 此外,您也不会重置外循环中每个候选者的 count 。因此,您将所有候选者的找到的除数一起计算,同时您想单独计算每个候选者。
  • In your inner loop you calculate candidate%divisor for all divisors, but only after the loop is finished you check if count should be incremented. So you only increment it only once per candidate, for the last divisor checked.
  • Also you do not reset count for each candidate in the outer loop. So you count the found divisors for all candidates together while you want to count for each candidate individually.
无言温柔 2024-10-17 22:16:42
#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 循环之前没有将计数分配为零。我改变了候选的顺序(从大到小),并纠正了一些语法错误。

感谢大家的鼓励性帮助和回答。 :) 我很高兴完成这件事,这样我就可以解决其他算法和问题。

#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;
}

Finally i have corrected my solution. The main problem was that i weren't assigning count to zero before the second for loop. I changed the order of candidate (big to small) and i corrected little syntax mistakes.

Thanks all you for your encouraging help and answers. :) I'm happy to have this done , so i can pass through other algorithms&problems.

饮惑 2024-10-17 22:16:42

一些需要记住的提示

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

Some hints to keep in mind

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
小猫一只 2024-10-17 22:16:42

为了清楚起见,有人重新格式化了代码,使其不同于原始提交的形式。在此过程中,他们修改了代码中的三个错误之一。

第一个错误是第二个 for 语句后面没有括号。因此,循环体仅包含第二个 for 语句后面的语句。通过阅读代码,很明显提问者希望重复执行第二个循环语句之后的所有内容。事实并非如此。

本质上,这个想法是:对于范围内的每个数字,尝试 1 和候选数字之间的所有数字。数一下分割它的人数。看看是否正好有 2。这是一个正确的算法,而说不除以 2 的答案是错误的。

然而,实现是这样做的:对于范围内的每个数字,将候选值除以 1 和候选值之间的每个数字。然后,完成所有除法后,检查最后一个结果是否为偶数,如果是,则在计数中加 1。所以,发生的情况是,您实际上只是在检查 candidate % Candidate == 0 是否如此,它总是这样做。

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

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

Someone has reformatted the code for clarity from its original submitted form. In doing so, they've modified one of the three mistakes in the code.

The first mistake was that the second for statement did not have brackets after it. As a result, the loop body consisted only of the statement which followed the second for statement. From reading the code, it's clear that the questioner intended everything after the second loop statement to be executed repeatedly. This is not what was happening.

Essentially, the idea was: for each number in the range, try all numbers between 1 and the candidate. Count the number of those which divide it. See if there are exactly 2. This is a correct algorithm and the answer which say to not divide by 2 is wrong.

However, the implementation was doing this: for each number in range, divide the candidate by every number between 1 and the candidate. Then, once you've done all that division, check to see if the last one came out even and if so, add 1 to the count. So, what's happening is that you're only actually checking to see if candidate % candidate == 0 which it always does.

The second mistake, is that the count is only reset when it gets to 2. So, what's happening is that the code, for any input, will return every other number. For each candidate, count++ happens exactly once. So it reaches 2 and gets reset every other time.

The third mistake is that once the inner-most loop is fixed, then the continue will do the wrong thing since it only continues the inner-most loop.

反话 2024-10-17 22:16:42

我知道您的代码仅用于教育目的,但是您应该考虑埃拉托斯特尼筛法,因为它可能是解决您的问题的最快算法。它的基本作用是:

  1. 首先考虑所有数字素数。
  2. 从 2 开始,您认为质数的所有倍数都不是质数。
  3. 转到下一个质数,并将其所有倍数设为非质数。

我认为通过阅读以下内容您会更好地理解该算法:
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

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

希望这有帮助!

I know your code is for educational purposes only, however you should consider Sieve of Eratosthenes as it would probably be the fastest algorithm for your problem. What it basically does is:

  1. At first consider all numbers prime numbers.
  2. Starting off with 2, you consider all the multiples of a prime number non-prime.
  3. Go to the next prime number and make all it's multiples non-prime.

I think you would get a better understanding of the algorithm by reading this:
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes

As for the implementation, just use an array which has all it's elements set to zero, and set the elements from prime number to prime number to one.

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文