线程“主”中的异常java.lang.StackOverflowError的 [英] Exception in thread "main" java.lang.StackOverflowError

查看:166
本文介绍了线程“主”中的异常java.lang.StackOverflowError的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一段代码,我无法弄清楚为什么它给我在线程mainjava.lang.StackOverflowError中的异常。



这是一个问题:

 给定一个正整数n,打印出Syracuse 
序列长度的总和,范围从1到n(含)。因此,例如,
长度(3)
的调用将返回序列的组合长度:
1
2 1
3 10 5 16 8 4 2 1
这是值:11.如果
的输入值小于1,则长度必须抛出IllegalArgumentException。

我的代码:

  import java.util.HashMap; 

public class Test {

HashMap< Integer,Integer> syraSumHashTable = new HashMap< Integer,Integer>();
$ b $ public Test(){

}

公共int长度(int n)抛出IllegalArgumentException {

int sum = 0;

if(n <1){
throw new IllegalArgumentException(Error !! Invalid Input!);
}

else {


(int i = 1; i <= n; i ++){

如果(syraSumHashTable.get(i)== null)
{
syraSumHashTable.put(i,printSyra(i,1));
sum + =(整数)syraSumHashTable.get(i);

}

else {

sum + =(Integer)syraSumHashTable.get(i);
}



}

归还金额;

}



}

private int printSyra(int num,int count){

int n = num;

if(n == 1){

return count;


else {
if(n%2 == 0){

return printSyra(n / 2,++ count);
}

else {

return printSyra((n * 3)+1,++ count);

}

}


}
}

驱动程序代码:

  public static void main(String [] args){
// TODO自动生成的方法存根
测试s1 = new Test();
System.out.println(s1.lengths(90090249));
//System.out.println(s1.lengths(5));
}


我知道问题在于递归。如果输入值很小,则不会发生该错误,例如:5.但是,如果数字很大,例如90090249,我在线程mainjava.lang.StackOverflowError中得到异常。感谢你的帮助。 :)



我几乎忘了错误消息:

  Exception in在Test.printSyra(Test.java:60)
在Test.printSyra(Test.java:65)
在Test.printSyra(Test。 Test.printSyra(Test.java:60)
(Test.printSyra(Test.java:60))
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:60)$ Test.printSyra(Test.java:60)
在Test.printSyra(Test.java:60)


解决方案

你的算法很好。然而, int 对于您的计算来说太小了,但是对于这个输入却失败了:

  printSyra(113383,1); 

在某个点整数溢出为负值,并且您的实现变得疯狂,无限递归。将 int num 更改为 long num ,您会很好 - 一段时间。稍后,您需要 BigInteger



请注意,根据Wikipedia上 Collat​​z猜想(粗体):


任何初始起始数量少于1亿的最长进展是63,728,127,其中<949步。对于少于10亿的起始数字,其数量为670,617,279,步数为986,对于数量少于100亿的数字,则是9,780,657,630,<1132步


总步数等于您可以预期的最大嵌套级别(堆栈深度)。所以即使是相对较大的数字 StackOverflowError 也不应该发生。使用 BigInteger 查看这个实现:
$ b

  private static int printSyra (BigInteger num,int count){
if(num.equals(BigInteger.ONE)){
return count;
}
if(num.mod(BigInteger.valueOf(2))。equals(BigInteger.ZERO)){
return printSyra(num.divide(BigInteger.valueOf(2)), count + 1);
} else {
return printSyra(num.multiply(BigInteger.valueOf(3)).add(BigInteger.ONE),count + 1);




$ b $ p
$ b

即使对于很大的值也可以使用:

  printSyra(new BigInteger(9780657630),0)// 1132 
printSyra(new BigInteger(104899295810901231), 0)// 2254


I have a piece of code and I could not figure out why it is giving me Exception in thread "main" java.lang.StackOverflowError.

This is the question:

Given a positive integer n, prints out the sum of the lengths of the Syracuse 
sequence starting in the range of 1 to n inclusive. So, for example, the call:
lengths(3)
will return the the combined length of the sequences:
1
2 1
3 10 5 16 8 4 2 1 
which is the value: 11. lengths must throw an IllegalArgumentException if 
its input value is less than one.

My Code:

import java.util.HashMap;

public class Test {

HashMap<Integer,Integer> syraSumHashTable = new HashMap<Integer,Integer>();

public Test(){

}

public int lengths(int n)throws IllegalArgumentException{

    int sum =0;

    if(n < 1){
        throw new IllegalArgumentException("Error!! Invalid Input!");
    }   

    else{


        for(int i =1; i<=n;i++){

            if(syraSumHashTable.get(i)==null)
            {
                syraSumHashTable.put(i, printSyra(i,1));
                sum += (Integer)syraSumHashTable.get(i);

            }

            else{

                sum += (Integer)syraSumHashTable.get(i);
            }



        }

        return sum;

    }



}

private int printSyra(int num, int count){

    int n = num;

    if(n == 1){

        return count;
    }

    else{   
            if(n%2==0){

                return printSyra(n/2, ++count);
            }

            else{

                return printSyra((n*3)+1, ++count) ;

            }

    }


}
}

Driver code:

public static void main(String[] args) {
    // TODO Auto-generated method stub
    Test s1 = new Test();
    System.out.println(s1.lengths(90090249));
    //System.out.println(s1.lengths(5));
}

. I know the problem lies with the recursion. The error does not occur if the input is a small value, example: 5. But when the number is huge, like 90090249, I got the Exception in thread "main" java.lang.StackOverflowError. Thanks all for your help. :)

I almost forgot the error msg:

Exception in thread "main" java.lang.StackOverflowError
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:65)
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:65)
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:60)
at Test.printSyra(Test.java:60)

解决方案

Your algorithm is fine. However int is too small for your computations, it fails for this input:

printSyra(113383, 1);

At some point integer overflows to negative value and your implementation goes crazy, recursing infinitely. Change int num to long num and you'll be fine - for some time. Later you'll need BigInteger.

Note that according to Wikipedia on Collatz conjecture (bold mine):

The longest progression for any initial starting number less than 100 million is 63,728,127, which has 949 steps. For starting numbers less than 1 billion it is 670,617,279, with 986 steps, and for numbers less than 10 billion it is 9,780,657,630, with 1132 steps.

The total number of steps is equivalent to maximum nesting level (stack depth) you can expect. So even for relatively big numbers StackOverflowError should not occur. Have a look at this implementation using BigInteger:

private static int printSyra(BigInteger num, int count) {
    if (num.equals(BigInteger.ONE)) {
        return count;
    }
    if (num.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO)) {
        return printSyra(num.divide(BigInteger.valueOf(2)), count + 1);
    } else {
        return printSyra(num.multiply(BigInteger.valueOf(3)).add(BigInteger.ONE), count + 1);
    }
}

It works even for very big values:

printSyra(new BigInteger("9780657630"), 0)  //1132
printSyra(new BigInteger("104899295810901231"), 0)  //2254

这篇关于线程“主”中的异常java.lang.StackOverflowError的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆