因此,该程序假设从GUI中获取包含整数操作数和四个算术运算符(+ - * /)的语法正确的中缀表达式并显示结果。我在括号中输入表达式时遇到麻烦。
例如,这个表达式
5+3-2
将返回6,但括号中的表达式相同
(5+3-2)
返回一个空堆栈异常。
我尽可能小心地试图通过这个,但我知道有用。编译器将错误指向第三个while循环,这表明我最好的猜测是堆栈valueStack当时没有两个值,但我似乎无法弄清楚原因。谁能帮我弄清楚我做错了什么?
public String infix(String expression)
{
expression=expression.replaceAll("[\t\n ]", "");
String operator = "*/+-";
int value1, value2;
char ch;
StringTokenizer tokenizer = new StringTokenizer(expression, operator, true);
Stack<Integer> valueStack = new Stack<Integer>();
Stack<Character> operatorStack = new Stack<Character>();
while(tokenizer.hasMoreTokens())
{
String token = tokenizer.nextToken();
if(isInteger(token) == true)
valueStack.push(Integer.parseInt(token));
else if(token.charAt(0) == '(')
operatorStack.push(token.charAt(0));
else if(token.charAt(0) == ')')
while(operatorStack.peek() != '(')
{
value1 = valueStack.pop();
value2 = valueStack.pop();
valueStack.push(solver(value1, value2, operatorStack.pop()));
operatorStack.pop();
}
else if(token.charAt(0) == '+' || token.charAt(0) == '-' || token.charAt(0) == '*' || token.charAt(0) == '/')
{
while(!operatorStack.isEmpty() && precedence(token.charAt(0)) <= precedence(operatorStack.peek()))
{
value1 = valueStack.pop();
value2 = valueStack.pop(); //empty stack error starts here
valueStack.push(solver(value1, value2, operatorStack.pop()));
}
operatorStack.push(token.charAt(0));
}
}
while(!operatorStack.isEmpty())
{
value1 = valueStack.pop();
value2 = valueStack.pop();
ch = operatorStack.pop();
valueStack.push(solver(value1, value2, ch));
}
String result = Integer.toString(valueStack.pop());
return result;
} //End of infix
public static boolean isInteger(String s)
{
try
{
Integer.parseInt(s);
}
catch(NumberFormatException e)
{
return false;
}
catch(NullPointerException e)
{
return false;
}
return true;
} // end of isInteger
public int solver( int value1, int value2, char operator)
{
try
{
if(operator == '*')
return value2 * value1;
else if(operator == '/')
return value2 / value1;
else if(operator == '+')
return value2 + value1;
else if(operator == '-')
return value2 - value1;
else
return 0;
}
catch(ArithmeticException e )
{
JOptionPane.showMessageDialog(null, "Division by Zero");
}
return 0;
} // end of solver
public int precedence(char op)
{
if(op == '+' || op == '-')
return 1;
else if(op == '*' || op == '/')
return 2;
else
return 0;
} // end of precedence
答案 0 :(得分:0)
首先,我只修复了带括号的表达式周围的崩溃错误。我没有测试其他的东西,对不起。
有一些问题(我在调试代码中包含了注释)但实质上你假设你在一个堆栈上有2个值,而实际上你只有一个。这是因为你穿的第一个号码从来没有被戴上,因为它有一个“(”附加它。第一个标记是“(5”而不是“(”,所以它永远不会到达5,无论如何这是代码哈哈
import java.util.*;
import javax.swing.JOptionPane;
public class Calc {
public String infix(String expression)
{
expression=expression.replaceAll("[\t\n ]", "");
String operator = "(*/+-)"; // I added (,) see line 20 for why ...
int value1, value2;
char ch;
StringTokenizer tokenizer = new StringTokenizer(expression, operator, true);
Stack<Integer> valueStack = new Stack<Integer>();
Stack<Character> operatorStack = new Stack<Character>();
while(tokenizer.hasMoreTokens())
{
String token = tokenizer.nextToken();
// the token here was "(5" when really it should be 5, therefore 5 doesn't get put on the value stack, which has consequences
// see line 37 ...
if(isInteger(token) == true)
valueStack.push(Integer.parseInt(token));
else if(token.charAt(0) == '(')
operatorStack.push(token.charAt(0));
else if(token.charAt(0) == ')')
while(operatorStack.peek() != '(') // also need to check if the stack is empty here ...
{
value1 = valueStack.pop();
value2 = valueStack.pop();
valueStack.push(solver(value1, value2, operatorStack.pop()));
operatorStack.pop();
// also need to check if the stack is empty here ...
if (operatorStack.isEmpty())
break;
}
else if(token.charAt(0) == '+' || token.charAt(0) == '-' || token.charAt(0) == '*' || token.charAt(0) == '/')
{
while(!operatorStack.isEmpty() && precedence(token.charAt(0)) <= precedence(operatorStack.peek()))
{ // the bug happens because there is only one value [3] on the valueStack, and here you assume there are 2 (should be 3,5)
value1 = valueStack.pop();
value2 = valueStack.pop(); //empty stack error starts here
valueStack.push(solver(value1, value2, operatorStack.pop()));
}
operatorStack.push(token.charAt(0));
}
}
while(!operatorStack.isEmpty())
{
value1 = valueStack.pop();
value2 = valueStack.pop();
ch = operatorStack.pop();
valueStack.push(solver(value1, value2, ch));
}
String result = Integer.toString(valueStack.pop());
return result;
} //End of infix
public static boolean isInteger(String s)
{
try
{
Integer.parseInt(s);
}
catch(NumberFormatException e)
{
return false;
}
catch(NullPointerException e)
{
return false;
}
return true;
} // end of isInteger
public int solver( int value1, int value2, char operator)
{
try
{
if(operator == '*')
return value2 * value1;
else if(operator == '/')
return value2 / value1;
else if(operator == '+')
return value2 + value1;
else if(operator == '-')
return value2 - value1;
else
return 0;
}
catch(ArithmeticException e )
{
JOptionPane.showMessageDialog(null, "Division by Zero");
}
return 0;
} // end of solver
public int precedence(char op)
{
if(op == '+' || op == '-')
return 1;
else if(op == '*' || op == '/')
return 2;
else
return 0;
} // end of precedence
public static void main (String [] args) {
Calc c = new Calc();
System.out.println(c.infix("(5+2-1)")); // heyy it works now :)
}
}
只需快速编辑,上面的代码仍然会为这样的表达式(5+(3 + 2))抛出异常,即嵌套括号,所以我也为此添加了一个快速(也许不是很漂亮)修复:< / p>
import java.util.*;
import javax.swing.JOptionPane;
public class Calc {
public String infix(String expression)
{
expression=expression.replaceAll("[\t\n ]", "");
String operator = "(*/+-)"; // I added (,) see line 20 for why ...
int value1, value2;
char ch;
StringTokenizer tokenizer = new StringTokenizer(expression, operator, true);
Stack<Integer> valueStack = new Stack<Integer>();
Stack<Character> operatorStack = new Stack<Character>();
// added this in:
boolean stopParsingBrackets = false;
while(tokenizer.hasMoreTokens())
{
String token = tokenizer.nextToken();
// the token here was "(5" when really it should be 5, therefore 5 doesn't get put on the value stack, which has consequences
// see line 37 ...
if(isInteger(token) == true)
valueStack.push(Integer.parseInt(token));
else if(token.charAt(0) == '(' && stopParsingBrackets)
operatorStack.push(token.charAt(0));
else if(token.charAt(0) == ')' && stopParsingBrackets)
while(operatorStack.peek() != '(') // also need to check if the stack is empty here ...
{
value1 = valueStack.pop();
value2 = valueStack.pop();
valueStack.push(solver(value1, value2, operatorStack.pop()));
operatorStack.pop();
// also need to check if the stack is empty here ...
if (operatorStack.isEmpty()) {
stopParsingBrackets = true;
}
}
else if(token.charAt(0) == '+' || token.charAt(0) == '-' || token.charAt(0) == '*' || token.charAt(0) == '/')
{
while(!operatorStack.isEmpty() && precedence(token.charAt(0)) <= precedence(operatorStack.peek()))
{ // the bug happens because there is only one value [3] on the valueStack, and here you assume there are 2 (should be 3,5)
value1 = valueStack.pop();
value2 = valueStack.pop(); //empty stack error starts here
valueStack.push(solver(value1, value2, operatorStack.pop()));
}
operatorStack.push(token.charAt(0));
}
}
while(!operatorStack.isEmpty())
{
value1 = valueStack.pop();
value2 = valueStack.pop();
ch = operatorStack.pop();
valueStack.push(solver(value1, value2, ch));
}
String result = Integer.toString(valueStack.pop());
return result;
} //End of infix
public static boolean isInteger(String s)
{
try
{
Integer.parseInt(s);
}
catch(NumberFormatException e)
{
return false;
}
catch(NullPointerException e)
{
return false;
}
return true;
} // end of isInteger
public int solver( int value1, int value2, char operator)
{
try
{
if(operator == '*')
return value2 * value1;
else if(operator == '/')
return value2 / value1;
else if(operator == '+')
return value2 + value1;
else if(operator == '-')
return value2 - value1;
else
return 0;
}
catch(ArithmeticException e )
{
JOptionPane.showMessageDialog(null, "Division by Zero");
}
return 0;
} // end of solver
public int precedence(char op)
{
if(op == '+' || op == '-')
return 1;
else if(op == '*' || op == '/')
return 2;
else
return 0;
} // end of precedence
public static void main (String [] args) {
Calc c = new Calc();
System.out.println(c.infix("(5+(2-1+2))")); // heyy it works now :)
}
}