[英]how to avoid ArrayIndexOutOfbounds Exception?
I am trying to solve a infix expression using stacks and my program seems to throw an ArrayIndexOutOfBoundsException
. 我试图使用堆栈解决中缀表达式,我的程序似乎抛出一个
ArrayIndexOutOfBoundsException
。
Can you guide me on how to solve my bug in the code? 你能指导我如何在代码中解决我的错误吗?
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);
}
}
On running it is like this: 在运行它是这样的:
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)
This is not an answer but a suggestion to make the program easier to debug - it won't fit in a comment :) 这不是一个答案,而是一个让程序更容易调试的建议 - 它不适合评论:)
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());
}
It seems to be a logical error (conceptual mistake?). 这似乎是一个逻辑错误(概念错误?)。
There is the attempt to evaluate an expression sequentially using tokens. 尝试使用令牌顺序评估表达式。 When the next
operation token
is available, the operation
is being applied, but there is no check that the value stack
size is greater or equal to the number of values required to perform (interpret) the operation before popping the values. 当下一个
operation token
可用时,正在应用operation
,但是没有检查value stack
大小是否大于或等于在弹出值之前执行(解释)操作所需的值的数量。 This is why the last printed message is Stack is isEmpty.
这就是为什么最后打印的消息是
Stack is isEmpty.
. 。
The algorithm — the infix expressions evaluation algorithm. 算法 - 中缀表达式评估算法。
If the goal is to learn how to design the algorithm, then try to design it by yourself. 如果目标是学习如何设计算法,那么尝试自己设计。 Otherwise, learn the algorithm using its description, for example, from this source .
否则,请使用其描述(例如,从此来源)学习算法。
Before updating the current implementation, please try to understand what is wrong with it: compare it with the designed or described version. 在更新当前实现之前,请尝试了解它的错误:将其与设计或描述的版本进行比较。 Right after that, update the implementation or create a new one if a lot of changes are required.
在此之后,如果需要进行大量更改,请更新实施或创建新实施。
Currently, I see a problem with operation precedence handling. 目前,我发现操作优先级处理存在问题。 Please consider the following operation handling:
请考虑以下操作处理:
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());
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.