在为特定测试用例执行程序时出现意外的代码行为。(在Java中)

时间:2012-01-28 11:04:03

标签: java logic

这是我编写的一段代码,用于检查在给定范围内数字的总和和数字的平方和是否为素数。如果它们都是素数,我只需增加计数器,最后打印计数器值。

for(int j = lb; j <= ub ; j++)
{
    temp = j;
    do
    {
        sd = sd + (temp%10);
            sosd = sosd + ((temp%10) * (temp%10));
        temp = temp/10;
    }while( temp != 0);
    for(int p = 2; p <= (sd/2) ; p++)
    {
        if( p == sd/2 )
            pf = 0;
        if( sd % p == 0 )
        {
            pf = 1;
            break;
        }
    }
    for(int p = 2; p <= (sosd/2) ; p++)
    {
        if( p == sosd/2 )
            pff = 0;
        if( sosd % p == 0 )
        {
            pff = 1;
            break;
        }
    }
    if( pf == 0 && pff == 0 )
        count++;
sd = 0;
sosd = 0;
}
System.out.println(count);

所有变量都已正确定义并声明(请使用变量名称)。 问题是:当我运行lb = 10到ub = 20时,我得到count = 4(这是正确的)。 但是当我运行lb = 1到ub = 20时,我得到计数​​= 3(这是错误的!而且我无法找到这是怎么回事,我尝试打印单个值只是为了发现有什么问题计数并且它最后一次没有增加。令我惊讶的是,它为我测试的第一个案例产生了正确的答案,这是这个案例的一个子集!)。 请帮忙!

3 个答案:

答案 0 :(得分:4)

通过添加适当的方法来分析代码会更好更容易,这些方法可以明确地提示他们正在做什么。这将消除以需要在循环中重置的危险方式依赖全局变量的需要,这是我们往往会忘记的事情。

定义三种方法:一种是对数字求和,一种是数字的平方和,另一种是检查数字是否为素数。之后,找到错误会更容易,因为您将调试单个方法。

检查以下重写:

static int sumOfDigits(int number){
      int sum = 0;
      while (number != 0) {
        sum += number % 10;
        number /= 10;
      }

      return sum;
    }


    static int sumOfSquaresOfDigits(int number){
      int sum = 0;
      int digit=0;
      while (number != 0) {
        digit=number % 10;
        sum += digit*digit;
        number /= 10;
      }

      return sum;
    }


    static boolean isPrime(int number) {
      //check if n is a multiple of 2
      if (number%2==0) return false;
      //if not, then just check the odds
      for(int i=3;i*i<=number;i+=2) {
        if(number%i==0)
          return false;
      }
      return true;
   }

现在定义了这些方法,代码变成这样:

  int count=0;
  int lb=1;
  int ub=20;
  for(int j = lb; j <= ub ; j++)
    if ( isPrime(sumOfDigits(j)) && isPrime(sumOfSquaresOfDigits(j)) )
      count++;  

  System.out.println(count);

注意:求和数字的代码取自here,我修改它以制作求和方格的版本。

检查素数的代码来自here

答案 1 :(得分:2)

问题在于两个内部for循环:

for (int p = 2; p <= (sd/2) ; p++)
{
    if( p == sd/2 )
        pf = 0;

在某些情况下,p不一定会达到sd/2,这意味着pf变量不会重置为0.只需尝试重置pf和{{1}在最外面的pff循环结束时为0:

for

修改
这是对您的代码的修改似乎对我来说很好:

pf = 0;
pff = 0;

答案 2 :(得分:1)

要检查数字n的素数,您可以将循环运行到 sqrt(n)而不是n / 2. 这将提高测试较大数字的效率。 sqrt(n)是一个更严格的界限。