繁体   English   中英

递归调用中的StackOverFlow异常

[英]StackOverFlow Exception in recursion calls

我尝试按位And编程a和b之间的数字范围。 可以有n个测试用例。
0<=a,b<=2^32
1<=n<=200

说明
1
2 4
计算: 2&3&4

输入
1
4009754624 4026531839

输出
Exception in thread "main" java.lang.StackOverflowError at Example.BitwiseAnd.calculate(BitwiseAnd.java:78)

代码

public class BitwiseAnd
{
    static long temp = 0;
    static long result[];

    public static void main(String[] args)
    {
        Scanner scan = new Scanner(System.in);
        int time = scan.nextInt();
        if(validateTime(time))
        {
            result = new long[time];
            for(int i=0;i<time;i++)
            {
                long arr[] = new long[2];
                arr[0] = scan.nextLong();
                temp=arr[0];
                arr[1] = scan.nextLong();
                if(validateNum(arr[0],arr[1]))
                {
                    result[i] = calculateUsingRecursion(arr[0],arr[1]);
                    //result[i] = calculateUsingForLoop(arr[0],arr[1]);
                }
                else
                {
                    System.out.println("Enter a valid numbers");
                }
            }
            printResult(result);
        }
        else
        {
            System.out.println("Enter a valid number of testcases");
        }
    }

    public static void printResult(long[] result)
    {
        for(int i=0;i<result.length;i++)
        {
            System.out.println(result[i]);
        }
    }

    public static boolean validateNum(long num1, long num2)
    {
        Long max = (long)Math.pow(2, 32);
        if(num1<0 || num1>max)
        {
            return false;
        }
        else if(num2<0 || num2>max)
        {
            return false;
        }
        return true;
    }

    public static boolean validateTime(int time)
    {
        if(time<1 || time>200)
        {
            return false;
        }
        return true;
    }

    private static long calculateUsingRecursion(long num1, long num2)
    {
        while(num1<num2)
        {
            num1=num1+1;
            temp=temp&num1;
            calculateUsingRecursion(num1, num2);
        }
        return temp;
    }

    private static long calculateUsingForLoop(long num1,long num2)
    {
        num1=num1+1;
        for(long i=num1 ; i<=num2 ; i++)
        {
            temp=temp&num1;
        }
        return temp;
    }
}

对于大量的数字,递归方法的计算使我抛出StackOverFlowException for循环可以正常工作。 我的问题是,为什么我们不能对大量输入进行递归? 以及如何通过递归来解决?

您的递归函数有点儿介于迭代和递归之间。 像这样更改它:

private static long calculateUsingRecursion(long num1, long num2, long temp) {

    // Stop condition
    if (num1 >= num2) {
        return temp;
    }      

    // Progression
    num1 = num1 + 1;
    temp = temp & num1;

    // Recursion
    return calculateUsingRecursion(num1, num2, temp);        
}

请注意,如果任何递归函数的递归太深,则将获得StackOverflowException。

您没有添加所有信息(例如完整的堆栈跟踪),并且代码中没有BitwiseAnd.calculate方法。

1)您在递归方法中使用了“ while”,但不应循环,因为这是由递归调用完成的,应改为使用“ if”。

2)堆栈的大小受到限制,因此方法无法在无限循环中调用自身。 使用输入4009754624和4026531839,它必须自称为16777215次。 背景资料需要更多的内存。 但是为了简化起见:Java必须为您的方法分配2个长参数16777215次,并且它只能在每个方法返回后重用它们。

因此,如果您进行多次迭代,则不要进行递归调用。

您根本不需要遍历所有这些数字。 您只需要查找对于间隔中的所有数字都恒定的位(否则它们的AND等于零)。

让我们从最高位到最低位进行迭代,并检查ab的值是否相同。 当它们在某个位置具有不同的位时,停止迭代:

long res = 0;
for (int bit = 32; bit >= 0; --bit) {
    long bita = a & (1L << bit);
    long bitb = b & (1L << bit);
    if (bita != bitb) break;
    res |= bita;
}

可运行的: https : //ideone.com/pkrUtV

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM