【问题标题】:Display prime number显示素数
【发布时间】:2015-10-07 12:58:11
【问题描述】:

我在下面编写的这个程序用于显示用户键入的列表(20 个数字)中的质数。但它只能将 2 和 3 检测为素数。我不知道为什么它不起作用。请告诉我错误在哪里并帮助我改进它。太清了。

#include <iostream>
#include <conio.h>
using namespace std;

void main ()
{
    int i,number,list[20];
    int t,p,prime=0;


    cout<<"please key 20 numbers from 0 to 99"<<endl;


    for(i=1;i<21;i++)
    {
        cin>>number;

        if((number<0)||(number>99))
        {
            cout<<"Please key in an integer from 0 to 99"<<endl;

        }

        list[i]=number;

    }


    for(p=1;p<21;p++)
    {
        for(t=2;t<list[p];t++)
        {
            if ( list[p]%t==0)
            {
                prime=prime+1;
            }
        }
            if (prime==0&&list[p]!=1)
            {
                cout<<"Prime numbers:"<<list[p]<<endl;
            }
    }

getch();
}

【问题讨论】:

  • &lt; 21 是对未定义行为的邀请;你的 list 有 20 个元素,所以循环应该类似于 for (int i = 0; i &lt; 20; i++)。您还故意忽略了数组中的元素 0;这不一定是个问题,但实际上浪费了数组的一个元素。
  • 您需要在内部循环开始之前设置prime = 0;。至于改进,请查看埃拉托色尼筛法或几乎任何其他关于 SO 上的素数的问题。您的代码几乎没有像主要测试那样低效。
  • 我已经这样做了,参考第8行。
  • 我的意思是“您需要将prime = 0; 设置为外部for 循环主体中的第一条语句,在内部for 循环开始之前”。您在程序开始时将其设置为零。当您输入 2 时,prime 永远不会增加,因此您正确地将 2 识别为素数;同上 3. 当你输入 4 时,prime 增加,所以它被识别为复合。但是,当您输入 5 时,素数不为零,因此它被视为合数。
  • 使用所有警告和调试信息编译您的程序,例如gcc -Wall -Wextra -g 如果使用 GCC。然后使用调试器,例如gdb 一步一步运行你的程序。阅读primality testprime numbers

标签: c arrays for-loop input primes


【解决方案1】:

因此,您的代码存在一些问题,但可以解决您的问题的只是算法问题。

当您开始 p 的下一次迭代时,您不会重置素数的值,因此在我们检测到第二个素数后它始终 > 0,您将永远不会再打印出任何数据。

改变这个:

for(p=1;p<21;p++)
{
    for(t=2;t<list[p];t++)
    {
        if ( list[p]%t==0)
        {
            prime=prime+1;
        }
    }
        if (prime==0&&list[p]!=1)
        {
            cout<<"Prime numbers:"<<list[p]<<endl;
        }
}

为此(我为 clairty 添加了一些括号,因此我们确定条件的计算结果符合我们的预期):

for(p=0;p<20;p++)
{
    for(t=2;t<list[p];t++)
    {
        if ( list[p]%t==0)
        {
            prime=prime+1;
        }
    }
        if ( (prime==0) && (list[p]!=1) )
        {
            cout<<"Prime numbers:"<<list[p]<<endl;
        }
        prime = 0;
}

您的问题将得到解决。

但是:我想重申一下,这并不能解决您所有的代码问题。确保您非常仔细地考虑输入部分以及您正在循环的内容(为什么 p 1 到 21?为什么不是 0 到 20 ;)数组在 C 中是零索引的,这意味着您的 20 个数字列表来自 list[0]到 list[19],您当前正在从 list[1] 循环到 list[20],这实际上超出了范围,我很惊讶您没有收到段错误!)

【讨论】:

  • 我不知道这会是个问题。不过,既然你们都劝我让迭代从0开始,那我就照办了。谢谢。
  • 不这样做有两个问题。首先,您忽略了列表中的第一个元素。您从 p=1 开始迭代,这是 list[1] ,它是列表中的第二个元素,可能会丢失一个素数。其次,转到 p
  • 我是初学者,很多规则不是很懂。感谢您的指导。
  • 在内循环之前设置prime = 0;会更好。实际上,您可以使用int prime = 0; 将其定义和初始化为外循环左大括号之后的第一个“语句”。引号中的“声明”,因为它在技术上是一个声明(定义),但它在功能上是一个声明。即使使用准标准 C 也可以做到这一点;变量可以声明在语句块的顶部(在{ 之后)。 C99 及更高版本允许您在需要时定义变量。限制变量的范围是一种很好的做法。
【解决方案2】:

如果有人输入“123”或“-15”,您的代码会发生什么情况?检查并查看是否可以修复错误。

当您解决了这个问题后,我们可以查看您的主要检查代码。提示:网络上有很多主要的测试代码示例。

【讨论】:

    【解决方案3】:

    检查一下

    #include<stdio.h>
    
    int main()
    {
       int n, i = 3, count, c;
    
       printf("Enter the number of prime numbers required\n");
       scanf("%d",&n);
    
       if ( n >= 1 )
       {
          printf("First %d prime numbers are :\n",n);
          printf("2\n");
       }
    
       for ( count = 2 ; count <= n ;  )
       {
          for ( c = 2 ; c <= i - 1 ; c++ )
          {
             if ( i%c == 0 )
                break;
          }
          if ( c == i )
          {
             printf("%d\n",i);
             count++;
          }
          i++;
       }
    
       return 0;
    }
    

    【讨论】:

    【解决方案4】:

    更高效的方式

    def print_hi(n):
    if(n == 1 ):
        return False;
    if( n == 2 or n == 3):
        return True;
    if(n % 2 == 0 or n % 3 == 0):
        return  False;
    
    for i in range (5,n,6):
        if( i * i <= n):
            if(n % i == 0 or n % (i+2) == 0):
                return False
            return True
    
    
    if __name__ == '__main__':
      x = print_hi(1032)
      print(x)
    

    【讨论】:

      猜你喜欢
      • 2016-01-23
      • 2015-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多