我正在尝试使用堆栈解决中缀表达式,我的程序似乎抛出了ArrayIndexOutOfBoundsException
。
你能指导我如何在代码中解决我的错误吗?
public class CS6084BTolani {
public static String evaluateInfix(String exps)
{
exps = exps.replaceAll(" ", "");//removing white spaces
System.out.println(exps);
StackADT<Double> values = new StackADT<Double>(exps.length());//Stack for Operands
StackADT<String> ops = new StackADT<String>(exps.length());//for operators
StringTokenizer tokens = new StringTokenizer(exps, "()^*/+-", true);//to seperate all the operands and operators
while(tokens.hasMoreTokens())
{
String tkn = tokens.nextToken();
if(tkn.equals("("))
{
ops.push(tkn);
System.out.println("ADDING to ops : "+ops.peek());
}
else if(tkn.matches("\\d+\\.\\d+")||tkn.matches("\\d+"))
{
values.push(Double.valueOf(tkn));
System.out.println("ADDING to values : "+values.peek());
}
else if (tkn.equals("^") || tkn.equals("*") || tkn.equals("/") || tkn.equals("+") || tkn.equals("-"))
{
while (!ops.isEmpty() && hasPrecedence(tkn, ops.peek()))
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
System.out.println("ADDING to values: "+values.peek());
// Push current token to 'ops'.
ops.push(tkn);
System.out.println("ADDING to ops: "+ops.peek());
}
else if(tkn.equals(")"))
{
while (!(ops.peek()).equals("("))
{
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
System.out.println("ADDING to values: "+values.peek());
}
ops.pop();
}
}
while (!ops.isEmpty())
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
// Top of 'values' contains result, return it
return String.valueOf(values.pop());
}
public static boolean hasPrecedence(String op1, String op2)
{
if (op2 == "(" || op2 == "(")
return false;
if ( (op1 == "^" ) && (op2 == "+" || op2 == "-"))
return false;
if ( (op1 == "^" ) && (op2 == "*" || op2 == "/"))
return false;
if ( (op1 == "*" || op1 == "/") && (op2 == "+" || op2 == "-"))
return false;
else
return true;
}
public static double applyOp(String op, double b, double a)
{
switch (op)
{
case "^":
return Math.pow(a,b);
case "+":
return a + b;
case "-":
return a - b;
case "*":
return a * b;
case "/":
if (b == 0)
throw new
UnsupportedOperationException("Cannot divide by zero");
return a / b;
}
return 0;
}
public static void main(String a[]) throws Exception
{
//Input ip = new Input("inputData4B.txt");
String expOne = "(100.0 + 2.3)";//ip.getFirstString();
System.out.println("Answer: "+evaluateInfix(expOne));
//String expTwo = ip.getSecondString();
//System.out.println("Answer: "+evaluateInfix(expTwo));
//String expThree = ip.getThirdString();
//System.out.println("Answer: "+evaluateInfix(expThree));
//String expFour = ip.getFourthString();
//System.out.println("Answer: "+evaluateInfix(expFour));
}
}
class StackADT<T extends Object> {
private int stackSize;
private T[] stackArr;
private int top;
public StackADT(int size)
{
stackSize = size;
stackArr = (T[]) new Object[stackSize];
top = -1;
}
public void push(T element){
stackArr[++top] = element;
}
public T pop()
{
if(isEmpty())
{
System.out.println("Stack is isEmpty.");
}
T element = stackArr[top--];
return element;
}
public T peek()
{
return stackArr[top];
}
public boolean isEmpty()
{
return (top == -1);
}
}
在运行时它是这样的:
java CS6084BTolani
(100.0+2.3)
ADDING to ops : (
ADDING to values : 100.0
Stack is isEmpty.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at StackADT.pop(CS6084BTolani.java:139)
at CS6084BTolani.evaluateInfix(CS6084BTolani.java:38)
at CS6084BTolani.main(CS6084BTolani.java:102)
答案 0 :(得分:0)
这不是答案,而是建议让程序更容易调试 - 它不符合评论:)
else if (tkn.equals("^") || tkn.equals("*") || tkn.equals("/") || tkn.equals("+") || tkn.equals("-"))
{
while (!ops.isEmpty() && hasPrecedence(tkn, ops.peek())) {
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
System.out.println("ADDING calculations to values: "+values.peek());
}
答案 1 :(得分:0)
这似乎是一个逻辑错误(概念错误?)。
尝试使用令牌依次评估表达式。
当下一个operation token
可用时,正在应用operation
,但不会检查value stack
大小是否大于或等于执行(解释)所需的值的数量弹出值之前的操作。这就是最后打印的邮件是Stack is isEmpty.
。
算法 - 中缀表达式评估算法。
如果目标是学习如何设计算法,那么请尝试自己设计。 否则,请使用其描述学习算法,例如,从this source。
在更新当前实现之前,请尝试了解它的错误:将其与设计或描述的版本进行比较。在此之后,如果需要进行大量更改,请更新实施或创建新实施。
目前,我发现操作优先处理存在问题。请考虑以下操作处理:
else if (tkn.equals("^") || tkn.equals("*") || tkn.equals("/") || tkn.equals("+") || tkn.equals("-")) {
if (!ops.isEmpty() && !hasPrecedence(tkn, ops.peek())) {
values.push(applyOp(ops.pop(), values.pop(), values.pop()));
System.out.println("ADDING to values: " + values.peek());
}
else {
// Push current token to 'ops'.
ops.push(tkn);
System.out.println("ADDING to ops: " + ops.peek());
}
}