是什么导致我的代码中的StackoverFlowError?

时间:2019-04-28 18:44:08

标签: java recursion integer stack stack-overflow

我需要编写两种解决方法。其中之一检查需要从最高有效数字到最低有效数字进行枚举的候选值。例如,如果数字是三位数,则必须是124 126 128 134 136 138 146 148 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 :(得分:0)

您喜欢递归:-)。这个函数对怎么样:

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,所有这样的数字都适合一个整数。另外,所有数字都不会大于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。但这只会混淆代码。