【问题标题】:Issue with FOR loop repeatingFOR循环重复问题
【发布时间】:2015-04-13 16:36:00
【问题描述】:

任务是找出一个数是否是素数。我做了一些研究并想出了以下代码:

    using System;

class PrimeOrNot
{
    static void Main()
    {
        Console.WriteLine("Write a natural number:");
        int number = int.Parse(Console.ReadLine());
        if (number == 1)
        {
            Console.WriteLine("Not prime"); //is 1 prime?
        }
        if (number == 2)
        {
            Console.WriteLine("Is Prime");
        }

        if (number % 2 == 0)
        {
            Console.WriteLine("Not prime");
        }
        else
        {
            for (int i = 3; i < number; i += 2)
            {
                if (number % i == 0)
                {
                    Console.WriteLine("Not Prime");
                }
                else
                {
                    Console.WriteLine("Is Prime");
                }
            }
        }
    }
}

问题是,如果数字一直通过测试到那个 FOR 函数,它就会变得很时髦。如果它是素数,它会打印很多“Is Prime”,如果不是,它会打印很多“Is Prime”和一些“Not Prime”。我一步一步调试它,看看问题出在哪里,但我想不出解决办法。

那么我该如何处理呢?

编辑:

所以我一开始就按照 Frank 建议的方式缩小了 IF,然后使用了 BradleyDotNET 的代码,瞧。今天我学习了打破循环。我最终得到的代码是这样的:

using System;

class PrimeOrNot
{
    static void Main()
    {
        Console.WriteLine("Write a natural number:");
        int number = int.Parse(Console.ReadLine());
        bool isPrime = true;
        if (number > 1 && number % 2 != 0)
        {
            for (int i = 3; isPrime && i < number; i += 2)
            {
                if (number % i == 0)
                {
                    isPrime = false;
                    break;
                }
            }
        }
        else
        {
            isPrime = false;
        }

        if (isPrime)
            Console.WriteLine("Number is prime!");
        else
            Console.WriteLine("Number is not prime.");
    }
}

【问题讨论】:

  • 学究式地讲,if、else 和 for 都不是运算符。 :)
  • 每次循环迭代都会打印两条消息之一。也许您打算将结果存储到某种 bool 变量中。然后稍后检查结果并打印“Prime”或“not”
  • @Almo 我知道!抱歉,我很新,忘记了这个词。
  • 提示:如果您将“确定一个数是否为素数”的操作提取到一个单独的方法中,将会更轻松。然后,您可以在知道答案后立即返回 - 并且您当前在哪里打印“Is Prime”,您知道答案...

标签: c# if-statement for-loop


【解决方案1】:

首先,该代码并没有真正检查数字是否为素数。

当你进入 for 循环时,你有这个条件:

if (number % i == 0)

检查 3 和您的数字之间的每个数字,以 2 递增。这使用模数(返回数字除以 i 的余数)。因此,基本上,对于该集合中将输入均分的每个数字,您将获得“非质数”输出,而对于其他每个数字,您将获得“质数”输出。

如果您只想要 一个 输出,请在循环期间设置一个布尔变量,然后在循环外检查它以执行输出。这是一个示例:

bool isPrime = true;

//Stopping the loop once we know its not prime is better
//Note that it won't even evaluate i < number if isPrime fails
for (int i = 3; isPrime && i < number; i += 2)
{
   if (number % i == 0)
   {
       isPrime = false;

       //Adding this line makes us more efficient
       //Some people don't like breaking flow like this though
       break; //We're done
   }
}

if (isPrime)
   Console.WriteLine("Number is prime!");
else
   Console.WriteLine("Number is not prime.");

请注意,代码包含两种提高效率的方法。不要在实际代码中同时使用两者,因为它们具有相同的效果:)

正如 Jon Skeet 在 cmets 中提到的,您可以将第一个块重构为一个方法,这是提高代码可读性和重用性的非常好的方法。

【讨论】:

  • 我会在 for 循环中添加一个 break 语句,或者更“高级”将它添加到 for 循环检查中。应该从 IMO 第 1 天开始教授高效。
  • for (int i = 3; isPrime && i
  • @Al-Muhandis 将这两种方法都添加到我的示例中,因为效率很重要。
  • @BradleyDotNET 你甚至可以只编码'isPrime = number % i != 0;'并摆脱 if ... 如果您在 for 标头中使用附加条件
  • @FlorianSchmidinger 是的,但是你在有条件的情况下进行分配,这几乎总是可怕的做法。当然不是要养成的习惯。
【解决方案2】:

首先,数字 1 被排除在素数之外。我不知道为什么,因为从技术上讲,它只能除以 1 和自身。嗯。 1 不是质数。

数字 2 绝对是质数,因为数字 2 只能被 1 和自身整除。

所以我可能会将前三个 if{} 更改为 if(n > 1 && n % 2 != 0)。这应该会让你进入第 3 名(我认为)。

然后让您的 for{} 循环在 else{} 处启动。不幸的是,我没有测试你的 int 号码。它正在测试您输入的数字和 3 之间的所有数字。

只需另一个 if 语句就可以了。无需遍历测试的所有数字。我认为我首先编写的 if 语句可能会做到这一点?嗯……

编辑:恕我直言,我不能添加 cmets,OP 要求测试他的 number 是否为素数,而不是 3 和他输入之间的所有数字。

【讨论】:

    【解决方案3】:

    您的问题可能是您的代码为从 3 到您的数字的每次循环迭代提供了建议。相反,您可能希望它只对每个奇数值进行评估,然后如果它发现规则的异常则中断,如下所示:

    using System;
    
    namespace IsItPrime
    {
        class Program
        {
            static void Main(string[] args)
            {
                bool exit = false;
                while (!exit) {
    
                    Console.WriteLine("Write a natural number:");
                    string answer = Console.ReadLine();
                    if (answer.Equals("x")) { 
                        exit = true;
                    }
                    else 
                    {
                        int number = int.Parse(answer);
    
                        if (number == 1)
                        {
                            Console.WriteLine("Not prime"); //is 1 prime?
                        }
                        else if (number == 2)
                        {
                            Console.WriteLine("Not Prime");
                        }
                        else if (number % 2 == 0)
                        {
                            Console.WriteLine("Not prime");
                        }
                        else
                        {
                            bool isPrime = false;
                            for (int i = 3; i < number; i += 2)
                            {
                                if (number % i == 0)
                                {
                                    isPrime = true;
                                    break;
                                }
                            }
    
                            if (isPrime)
                            {
                                Console.WriteLine("Not Prime");
                            }
                            else
                            {
                                Console.WriteLine("Is Prime");
                            }
                        }
    
                    }
                }
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      相关资源
      最近更新 更多