[英]how to avoid ArrayIndexOutOfbounds Exception?
我試圖使用堆棧解決中綴表達式,我的程序似乎拋出一個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)
這不是一個答案,而是一個讓程序更容易調試的建議 - 它不適合評論:)
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());
}
這似乎是一個邏輯錯誤(概念錯誤?)。
嘗試使用令牌順序評估表達式。 當下一個operation token
可用時,正在應用operation
,但是沒有檢查value stack
大小是否大於或等於在彈出值之前執行(解釋)操作所需的值的數量。 這就是為什么最后打印的消息是Stack is isEmpty.
。
算法 - 中綴表達式評估算法。
如果目標是學習如何設計算法,那么嘗試自己設計。 否則,請使用其描述(例如,從此來源)學習算法。
在更新當前實現之前,請嘗試了解它的錯誤:將其與設計或描述的版本進行比較。 在此之后,如果需要進行大量更改,請更新實施或創建新實施。
目前,我發現操作優先級處理存在問題。 請考慮以下操作處理:
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.