我在课堂上有以下代码......
String processor()
{
Stack<Character> stack = new Stack<>();
while (curr < infixExpr.length())
{
// assigning the current index position of string in infix expression to a variable to reduce amount of repeated code
Character element = infixExpr.charAt(curr);
if (isOperand(element))
{
postfixExpr += "" + element;
}
else if (element == '(')
{
stack.push(element);
}
else if (element == ')')
{
while (!stack.peek().equals('('))
{
postfixExpr += stack.pop(); // adding all items in stack after ( and before )
}
stack.pop(); // this should pop the stack of the waiting pushed ( paren and remove it from our postfix expression, basically ignoring it
// right paren found to trigger this else if statement was never pushed onto the stack nor assigned to the postfix expression, also ignored
}
else //*must be an operator then
{
while (OrdOpsTable.getOperatorPrecedence(stack.peek(), true) > OrdOpsTable.getOperatorPrecedence(element, false)) // flag, 'true' to signify this is from the stack. ALso, compare if it has higher precedence over the current operator
{
postfixExpr += stack.pop(); // placing found operator to end of postfix expression
}
stack.push(element);
}
curr++;
}
while (!stack.isEmpty())
{
postfixExpr += stack.pop();
}
return postfixExpr;
}
在方法“getOperatorPrecedence”参数中,我有一个名为 stack 的Stack实例,调用方法 peek ,返回一个Character Object。正如字段元素所示,元素是字符对象类型。我在方法参数中创建了一个简单的标志布尔值,以使其变得简单。
因此,“getOperatorPrecedence”位于另一个名为“OrdOpsTable”的类文件中......
public final class OrdOpsTable<T> extends ArrayList
{
// INITIALIZERS
private static Character[] table = {'(','+','-','*','/','%','^'};
private static ArrayList<OperatorValues> ON_stack = new ArrayList<>();
private static ArrayList<OperatorValues> ON_curr = new ArrayList<>();
private T FROM_stack = null;
private T FROM_curr = null;
// CONSTRUCTOR
private OrdOpsTable(T curr)
{
setOperatorPrecedence();
if (curr.getClass() == Stack.class)
this.FROM_stack = curr;
else
this.FROM_curr = curr;
}
// METHODS
private static void setOperatorPrecedence()
{
// this method just sets the unique values of each operator to two arrays
int i = 0;
for (char op : table)
{
switch(op)
{
case '(':
ON_stack.add(i, new OperatorValues(op, 0));
ON_curr.add(i, new OperatorValues(op, 100));
break;
case '+':
ON_stack.add(i, new OperatorValues(op, 2));
ON_curr.add(i, new OperatorValues(op, 1));
break;
case '-':
ON_stack.add(i, new OperatorValues(op, 2));
ON_curr.add(i, new OperatorValues(op, 1));
break;
case '*':
ON_stack.add(i, new OperatorValues(op, 4));
ON_curr.add(i, new OperatorValues(op, 3));
break;
case '/':
ON_stack.add(i, new OperatorValues(op, 4));
ON_curr.add(i, new OperatorValues(op, 3));
break;
case '%':
ON_stack.add(i, new OperatorValues(op, 4));
ON_curr.add(i, new OperatorValues(op, 3));
break;
case '^':
ON_stack.add(i, new OperatorValues(op, 5));
ON_curr.add(i, new OperatorValues(op, 6));
break;
}
i++;
}
}
public static int getOperatorPrecedence(Object curr, boolean FROM_stack)
{
setOperatorPrecedence();
if (FROM_stack)
{
return ON_stack.get(ON_stack.indexOf(curr)).value;
}
else
{
return ON_curr.get(ON_stack.indexOf(curr)).value;
}
}
/* SUBCLASS */
private static class OperatorValues
{
// FIELDS
private char operator;
private int value;
// CONSTRUCTOR
OperatorValues(char operator, int value)
{
this.operator = operator;
this.value = value;
}
// METHOD
char getOperator()
{
return this.operator;
}
int getValue()
{
return this.value;
}
public String toString()
{
return this.operator;
}
}
我需要帮助的是找到一种方法来正确返回
的两个实例的OperatorValue子类字段值return ON_stack.get(ON_stack.indexOf(curr)).value;
and
return ON_curr.get(ON_stack.indexOf(curr)).value;
我收到以下错误...
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:418)
at java.util.ArrayList.get(ArrayList.java:431)
at OrdOpsTable.getOperatorPrecedence(OrdOpsTable.java:79)
at PostfixParser.processor(PostfixParser.java:57)
at InfixPostfixTester.main(InfixPostfixTester.java:78)
当我调试并遵循此问题时,问题出在“Character”类“equals”中。首先,当我强制进入有问题的第一个return语句时,它会转到ArrayList中的indexOf()......
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
当调试器在这里遇到.equals方法时,它会进入Character类......
public boolean equals(Object obj) {
if (obj instanceof Character) {
return value == ((Character)obj).charValue();
}
return false;
}
这里的问题是此equals方法中的IF语句在此比较中失败。它似乎将obj与我自定义的OperatorValues类的toString()进行比较,它显然不是Character类的实例。所以,它失败了,因为它将“(”作为一个字符进行比较。我需要它来比较'('在此方法中触发'true'。
举一个例子,我在方法setOperatorPrecedence()中的OrdOpsTable类中分配了char'('在一个数组中带有'0'的int,在另一个数组中有'100',如上所示。这里调用类equals()方法而不使用OperatorValues类的toString(),我的调试器说curr的内联值'('在这个相等的方法中显示',obj:OrdOpsTable $ OperatorValues @ 636。
如果有办法让OperatorValues中的toString()方法返回一个Character而不是String。如果我这样做,这当然会导致错误。关于你将在这里做什么的任何建议?
*注意:如果我需要为您提供更多信息,请与我们联系。这是一个班级的家庭作业,我花了很多时间坚持这一部分,我已经无情地尝试过。我需要一些外包帮助来理解我所缺少的东西。
答案 0 :(得分:0)
我想通了,我将Character类的所有内容更改为String类,并在我的OrdOpsTable类中更改getOperatorPrecedence()方法,以强制从我的自定义OperatorValues类的本机类到String类进行比较,我这样做了...
return ON_stack.get(ON_stack.toString().indexOf(curr)).getValue();
感谢所有参与帮助的人,感谢他们。