Неожиданное поведение кода при выполнении программы для конкретных тестовых случаев. (На Java) - PullRequest
0 голосов
/ 28 января 2012

Вот фрагмент кода, который я написал, чтобы проверить, являются ли сумма цифр и сумма квадратов цифр числа простыми в заданном диапазоне. Если они оба простые, я просто увеличиваю счетчик и, в конечном итоге, печатаю значение счетчика.

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 ]

4 голосов
/ 28 января 2012

Было бы лучше и проще анализировать код с добавлением правильных методов, которые явно дают подсказку о том, что они делают.это избавит от необходимости полагаться на глобальные переменные таким опасным способом, когда им нужно сбрасывать в циклах, что мы склонны забывать.

определяют три метода: один для суммирования цифр, один для суммированияквадраты цифр и один, чтобы проверить, является ли число простым.после этого поиск ошибок будет проще, поскольку вы будете отлаживать отдельные методы.

проверьте следующее переписывание:

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

Примечание: код для суммирования цифр был взят из здесь , и я изменил его, чтобы сделать версию для суммирования квадратов.

код для проверки простого числа был взят из здесь

2 голосов
/ 28 января 2012

Проблема заключается в двух внутренних циклах for:

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

В некоторых случаях p не обязательно достигнет sd/2, что означает, что переменная pf не будет сброшена в0. Просто попробуйте сбросить pf и pff на 0 в конце вашей внешней for петли:

pf = 0;
pff = 0;

РЕДАКТИРОВАТЬ:
Вот модификация вашегокод, который, кажется, работает нормально для меня:

    for (int j = lb; j <= ub; j++) {
        sd = 0;
        sosd = 0;
        pf = 0;
        pff = 0;
        temp = j;
        do {
            sd = sd + (temp % 10);
            sosd = sosd + ((temp % 10) * (temp % 10));
            temp = temp / 10;
        } while (temp != 0);
        // Check for 1
        if (sd == 1 || sosd == 1) continue;
        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++;
        }
    }
    System.out.println(count);
1 голос
/ 30 января 2012

Кстати, чтобы проверить простоту числа n, вы можете запустить цикл до sqrt (n) вместо n / 2. Это повысит эффективность тестирования больших чисел. sqrt (n) является более строгим ограничением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...