Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用前缀表达式计算器获取java.lang.OutOfMemory错误_Java_Stack_Prefix_Evaluator - Fatal编程技术网

使用前缀表达式计算器获取java.lang.OutOfMemory错误

使用前缀表达式计算器获取java.lang.OutOfMemory错误,java,stack,prefix,evaluator,Java,Stack,Prefix,Evaluator,下面是计算前缀表达式的代码。我首先将表达式读入inputArray,它允许我从右向左读取,然后使用evaluationArray执行操作。此行出现内存不足错误:evaluationStack.push(数字); 我不知道为什么会这样。任何帮助都将不胜感激 导入java.util.* public class PrefixEvaluator { //evaluates a prefix expression public static int evaluate(String in

下面是计算前缀表达式的代码。我首先将表达式读入inputArray,它允许我从右向左读取,然后使用evaluationArray执行操作。此行出现内存不足错误:evaluationStack.push(数字); 我不知道为什么会这样。任何帮助都将不胜感激

导入java.util.*

public class PrefixEvaluator 
{
    //evaluates a prefix expression
    public static int evaluate(String input)
    {
        int number, leftOperand, rightOperand, result;
        char operator;
        String inputToken = null;

        //create input stack
        Stack<String> inputStack = new Stack<String>();
        //create an integer stack
        Stack<Integer> evaluationStack = new Stack<Integer>();


        //create string tokenizer containing input string
        StringTokenizer tokenizer = new StringTokenizer(input);

        //read string into a stack
        while (tokenizer.hasMoreTokens())
        {
            inputToken = tokenizer.nextToken(); //get next token
                inputStack.push(inputToken);   //push token     
        }


        while (inputStack.isEmpty() != true)
        {      
           //System.out.println(inputStack.pop());

            if (isNumber(inputToken))
            {
                number = Integer.parseInt(inputToken);
                evaluationStack.push(number);
            }
            else                         //if token is operator
            {
                operator = inputToken.charAt(0);   //get operator
                rightOperand = evaluationStack.pop();
                leftOperand  = evaluationStack.pop();
                result = evaluation(operator, leftOperand, rightOperand);
                evaluationStack.push(result);
            }
        }
        return evaluationStack.pop();
    }

    //tests whether token is a number
    private static boolean isNumber(String token)
    {
        char first = token.charAt(0);
        if (Character.isDigit(first))
            return true;
        else
            return false;

    }

    //perform an operation on two operands
    private static int evaluation(char operator, int leftOperand, int rightOperand)
    {
        if (operator == '+')
            return leftOperand + rightOperand;
        else if (operator == '-')
            return leftOperand - rightOperand;
        else if (operator == '*')
            return leftOperand * rightOperand;
        else if (operator == '%')
            return leftOperand % rightOperand;
        else
            return leftOperand / rightOperand;

    }


    public static void main (String [] args)
    {
        evaluate("* 4 - 165 235");
    }

}
公共类前缀赋值器
{
//计算前缀表达式的值
公共静态int求值(字符串输入)
{
整数,左操作数,右操作数,结果;
字符算子;
字符串inputToken=null;
//创建输入堆栈
Stack inputStack=新堆栈();
//创建一个整数堆栈
堆栈求值堆栈=新堆栈();
//创建包含输入字符串的字符串标记器
StringTokenizer tokenizer=新的StringTokenizer(输入);
//将字符串读入堆栈
while(tokenizer.hasMoreTokens())
{
inputToken=tokenizer.nextToken();//获取下一个令牌
inputStack.push(InputOken);//推送令牌
}
while(inputStack.isEmpty()!=true)
{      
//System.out.println(inputStack.pop());
如果(isNumber(输入输入))
{
数字=整数.parseInt(inputOken);
evaluationStack.push(编号);
}
else//如果令牌是运算符
{
运算符=inputToken.charAt(0);//获取运算符
RightOperator=evaluationStack.pop();
LeftOperator=evaluationStack.pop();
结果=求值(运算符、左操作数、右操作数);
evaluationStack.push(结果);
}
}
返回evaluationStack.pop();
}
//测试令牌是否为数字
私有静态布尔isNumber(字符串标记)
{
char first=token.charAt(0);
if(字符isDigit(第一个))
返回true;
其他的
返回false;
}
//对两个操作数执行操作
私有静态整型求值(字符运算符、整型左操作数、整型右操作数)
{
if(运算符=='+')
返回左操作数+右操作数;
else if(运算符=='-')
返回左操作数-右操作数;
else if(运算符=='*')
返回左操作数*右操作数;
else if(运算符=“%”)
返回LeftOperator%RightOperator;
其他的
返回左操作数/右操作数;
}
公共静态void main(字符串[]args)
{
评估(“*4-165 235”);
}
}

如果在调试器中单步执行代码,您将看到此代码是一个无限循环

    while (inputStack.isEmpty() != true)
    {      
       //System.out.println(inputStack.pop());

        if (isNumber(inputToken))
        {
            number = Integer.parseInt(inputToken);
            evaluationStack.push(number);
您一直在测试InputOken并将其添加到堆栈中,但您从未更改它,因此它会一直运行,直到内存耗尽为止

也许您打算在循环开始时使用它

       inputToken = inputStack.pop();
如果你也加上

System.out.println(evaluate("* 4 - 165 235"));
它打印

280

我建议您逐步完成调试器中的代码,您应该会看到其中一个集合比您预期的要大得多。我还建议您找到最简单的测试用例来处理此错误。在第二个测试用例中,inputStack上唯一的pop操作被注释掉,并且没有“中断”,这意味着while循环永远是一个!因此,内存不足,即您一直在evaluationStack中推送元素,直到您没有内存为止。更具体地说,一旦isNumber(InputOken)为真,这肯定会发生,因为此变量在为真时不会再次更新。我不明白。我在else部分中弹出evaluationStack,但您的inputStack从不为空,因此无限循环哦,好的,弹出堆栈不会清空它,并且大小保持不变。我现在明白了。thanks@EternalPunishment您可以在代码中调用
pop()
,而该代码从未被调用,因为它被卡在无限循环中。如果您使用调试器来查看它在做什么,那么这将更有意义。