Что вызывает StackoverFlowError в моем коде? - PullRequest
0 голосов
/ 28 апреля 2019

Мне нужно написать два метода отвода.Один из них проверяет значения-кандидаты, которые необходимо перечислить от самых значимых до наименее значимых цифр.Например, если числа состоят из трех цифр, они должны быть 124 126 128 134 136 138 146 148 156 и т. Д. До 999 (также четные).

Я написал две из них, но в одной, двух и трех цифрах проблем нет, однако после четырех цифр что-то вызывает java.lang.StackOverflowError Как я могу решить эту проблему?

  public boolean checkRec(int num)
   {
      String numLong = String.valueOf(num);
      if((Integer.valueOf(numLong.substring(numLong.length()-1)) % 2) != 0)
         return false;      
      if(numLong.length() == 1)
         return true;
      else
      {
         if(Integer.valueOf(numLong.substring(0,1)) >= Integer.valueOf(numLong.substring(1,2)))
         {
           // System.out.println("asd");
          return false;
         }
         numLong = numLong.substring(1);
         num = Integer.valueOf(numLong);
         return checkRec(num);
      }
   }
public String orderAndPrint(int num, int decimal)
       {
          if(num >= Math.pow(10, decimal+1))
            return "End";
          else
          {
             if(checkRec(num))
             {
                return "" + num + " " + orderAndPrint((num + 2), decimal);
             }
             return orderAndPrint((num + 2), decimal);
          }

1 Ответ

0 голосов
/ 24 мая 2019

Вам нравятся рекурсии :-).Как насчет этой пары функций:

public boolean check(int num)
{
    // This is actually unnecessary as check is called only for even numbers
    if ((num % 2) != 0)
        return false;
    int prev_digit = 10;
    while (num > 0) {
        int last_digit = num % 10;
        if (last_digit >= prev_digit)
            return false;
        prev_digit = last_digit;
        num = num / 10;
    }
    return true;
}

public String orderAndPrint(int decimal)
{
    String outstr = ""
    int last_num = Math.pow(10, decimal);
    int num = 2;
    for ( ; num < last_num; num += 2) {
        if (check(num))
            outstr = outstr + num + " ";
    }
    return outstr + "End";
}

Но этот фрагмент кода просто копирует то, что вы сделали более эффективно, без рекурсии.

Однако вы можете написать код, чтобы просто сгенерировать соответствующие числа, и там вам действительно нужна рекурсия.Обратите внимание, что наибольшее возможное такое число - 12345678, поэтому максимальное количество цифр - 8, и все такие числа помещаются в int.Кроме того, ни одна из цифр не будет больше 8, и только последняя может быть 8.

public String addnumbers (int n, int digitsleft, String outstr)
{
    int d;
    int last_digit = n % 10;
    if (digitsleft == 1) {
        d = (last_digit+1) % 2 == 0 ? last_digit+1 : last_digit+2;
        for ( ; d <= 8; d += 2) {
            outstr = outstr + (10*n+d) + " ";
        }
    }
    else {
        for (d=last_digit+1; d < 8; ++d) {
            outstr = addnumbers(10*n+d, digitsleft-1, outstr);
        }
    }
    return outstr;
}
public String orderAndPrint(int decimal)
{
    // Assume decimal is at least 1
    String outstr = "2 4 6 8 "
    int d;

    decimal = Math.min(8, decimal);
    for (d = 1; d < 8; ++d) {
        outstr = addnumbers(d, decimal-1, outstr);
    }
    return outstr + "End";
}

Обратите внимание, что это может быть ускорено путем использования лучшей верхней границы d в циклах.Например, если после текущей есть еще 2 цифры, то d не может быть больше 6. Но это просто запутало бы код.

...