Java BigInteger上的OutOfMemoryError

Java BigInteger上的OutOfMemoryError,java,biginteger,out-of-memory,Java,Biginteger,Out Of Memory,我正在为大整数(仅*、^和!)编写一个波兰语符号计算器,在我减去大整数的行上,我得到了一个OutOfMemoryError。一个让阶乘工作,为什么 package polish_calculator; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.math.BigInteger; import java.util.Stack; p

我正在为大整数(仅*、^和!)编写一个波兰语符号计算器,在我减去大整数的行上,我得到了一个
OutOfMemoryError
。一个
让阶乘工作,为什么

package polish_calculator;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.Stack;

public class Main {
    static BigInteger factorial(BigInteger number){
        Stack <BigInteger> factorialStack = new Stack<BigInteger>();
        factorialStack.push(number);

        while (!number.equals(BigInteger.ONE)){ //load the stack
            factorialStack.push(number.subtract(BigInteger.ONE)); // here's the error
        }

        BigInteger result = BigInteger.ONE;

        while(!factorialStack.empty()){ // empty and multiply the stack
            result.multiply(factorialStack.pop());
        }

        return result;
    }


    public static void main(String[] args) throws IOException {

        BigInteger testFactorial = new BigInteger("12");
        System.out.println(factorial(testFactorial));
        Stack <String> stack = new Stack<String>();
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String readExpression = br.readLine();
        while(!readExpression.equals("")){
            String [] splittedExpression = readExpression.split(" ");
            for(int i=0; i<splittedExpression.length;i++){
                if(splittedExpression[i].equals("*"))
                {
                    BigInteger operand1 = new BigInteger(stack.pop());
                    BigInteger operand2 = new BigInteger(stack.pop());
                    BigInteger result = operand1.multiply(operand2);
                    String stackString = result.toString();
                    stack.push(stackString);
                }
                if(splittedExpression[i].equals("^"))
                {
                    BigInteger operand1 = new BigInteger(stack.pop());
                    BigInteger operand2 = new BigInteger(stack.pop());
                    BigInteger result = operand1.modPow(operand2, BigInteger.ONE);
                    String stackString = result.toString();
                    stack.push(stackString);
                }

                if(splittedExpression[i].equals("!"))
                {
                    BigInteger operand1 = new BigInteger(stack.pop());
                    BigInteger result = factorial(operand1);

                    String stackString = result.toString();
                    stack.push(stackString);
                }
                else{ //it's an integer
                    stack.push(splittedExpression[i]);
               }
            } // end for splittedExpression.length
        }
    }
}

subtract生成一个新的BigInteger,您将其推送到堆栈上

但是原来的数字还是一样的,所以条件是一样的!number.equals(biginger.ONE)永远不会为真

因此,您将永远用数字1的副本填充堆栈,直到内存耗尽

编辑(再次):

请注意,这也是计算阶乘的一种非常消耗内存的方法,因为您需要在堆栈上推N个值来计算N!随着时间的推移,将它们相乘会更好,当然,在阶乘变得非常大之前,不需要大的N


有关高效计算大阶乘的详细信息,请参阅。

此。number.subtract()实际上并不修改数字。+1非常好@因此,您必须使用
number=number.subtract(biginger.ONE)然后
factorialStack.push(数字)
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
        at java.math.BigInteger.subtract(BigInteger.java:1118)
        at polish_calculator.Main.factorial(Main.java:45)
        at polish_calculator.Main.main(Main.java:65)
Java Result: 1