【问题标题】:my prime number checker function not working properly我的素数检查器功能无法正常工作
【发布时间】:2020-03-03 03:18:48
【问题描述】:

所以这个函数应该返回 0 如果不是素数,如果是素数则返回 1。我看错了吗?例如,当我给它 39 时,它说它返回 1,尽管 39 不是素数。

int is_prime(int number){
    if (number == 2) {
        return 1;
    }

    else{
        for(loop_counter ; loop_counter < number ; loop_counter++){

            if(number%loop_counter == 0){
                return 0;

            }
            else{
                return 1;
            }

    }
    }


}

【问题讨论】:

  • 循环在第一次迭代时停止,if/else 的两边都返回。这符合您的预期逻辑吗?
  • 去掉else return 1,并在函数末尾添加return 1
  • @harold:是的,如果不是素数,我希望它返回 0,如果是素数,则返回 1。
  • @Paul ogilvie:谢谢,成功了。
  • @KhaledYassen 是否证明 number%loop_counter != 0 证明 number 是素数?

标签: c loops for-loop primes


【解决方案1】:

关于:

for(loop_counter ; loop_counter < number ; loop_counter++){

变量:loop_counter 未初始化(甚至未声明)

也许你的意思是:

for( int loop_counter = 0; loop_counter < number ; loop_counter++){

以下建议代码:

  1. 干净编译
  2. 执行所需的功能
  3. 不是检查数字是否为素数的最快/最佳方法。相反,它是一种蛮力方法

OPs 贴出的代码有几个问题,如 cmets 对 OPs 问题的讨论,这里不再赘述。

现在,建议的代码:

int is_prime(int number)
{
    for( int loop_counter = 2 ; loop_counter < number ; loop_counter++)
    {
        if(number%loop_counter == 0)
        {
            return 0;
        }
    }

    return 1;
}

【讨论】:

  • @VladfromMoscow,函数定义有什么问题?
  • 例如对于等于 1 的数字,函数返回 1。
  • 1 不是质数。下面是素数的定义: 素数是一个大于 1 的整数,其唯一因数是 1 和它自己。因子是一个整数,可以整除成另一个数define prime number
  • 但是你的函数返回 1 表示等于 1 或例如 0 的数字。
  • @VladfromMoscow,我没有在提议的代码中包含错误检查。我希望 OP 在调用函数之前处理错误检查。
【解决方案2】:

在这个循环中

for(loop_counter ; loop_counter < number ; loop_counter++){

使用了一个未声明的变量loop_counter。如果它是全局变量,则不应在函数中使用它,因为至少不清楚它的值是什么。

同样在循环中,您将在number%loop_counter != 0 时立即中断其迭代。但这并不意味着这个数是素数。

如果用户将传递一个负数或零,则该函数将具有未定义的行为。

函数可以通过以下方式定义

int is_prime( unsigned int n )
{
    int prime = n % 2 == 0 ? n == 2 : n != 1;

    for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
    {
        prime = n % i != 0;
    }

    return prime;
}

该函数首先排除除2 之外的所有偶数,因为偶数不是素数。它还排除了数字1,因为根据定义,数字1 不是质数。

int prime = n % 2 == 0 ? n == 2 : n != 1;

所以在循环中考虑除数是没有意义的。

    for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
                                                   ^^^^^^

然后在循环中检查给定的奇数 n 是否可以被奇数除数整除

        prime = n % i != 0;

如果 n % i 等于 0,则变量 prime 的值为 0,并且由于循环中的条件,循环停止其迭代。

for ( unsigned int i = 3; prime && i <= n / i; i += 2 )
                          ^^^^^

也可以改写

for ( unsigned int i = 3; prime != 0 && i <= n / i; i += 2 )
                          ^^^^^^^^^^

【讨论】:

  • 我不完全理解你的函数体。澄清一下可以吗?
  • 次优。在第一次出现n % i == 0 时应中断循环
  • @SomeWittyUsername 确实如此,当n % i != 0 返回false 时,for 的条件变为 false,循环结束
  • 我喜欢你从最简单的问题中学到新东西。您对i &lt;= n / i 的使用非常棒。我通常使用i &lt;= sqrt(n),但我注意到您的方法在没有sqrt() 的情况下会收敛到相同的结果。伟大的!!!但也许i*i &lt;=n,因为我认为计算* 更容易/
  • @Afshin i*i &lt;= n 如果n 大于适合unsigned int 的最大平方数,则可能由于算术溢出而给出错误答案,因此i &lt;= n / i 更安全。如果编译器意识到sqrt(n) 是循环不变的并且不会在每次迭代中调用它,i &lt;= sqrt(n) 可能会更快。但它可以在循环之前进行计算以确保。 sqrt(n) 也可以用整数平方根函数代替,以避免引入浮点数学。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-23
  • 1970-01-01
  • 2013-11-06
  • 2013-10-29
  • 1970-01-01
相关资源
最近更新 更多