我一直试图找出我的代码的错误,但没有成功。除了评估后缀表达式之外,我还应该编写一个中缀到后缀的转换器。我的代码运行,但不幸的是,它没有返回正确的值。
我有一个计算器GUI,每当按下等号时,它就会调用下面显示的代码。计算器将一个用空格分隔的字符串作为参数传递。然后,我在这个空格分隔的字符串上使用字符串标记器,然后从那里开始工作。如果有帮助的话,我可以提供计算器GUI的代码。
我的问题在于计算器提供的答案。例如,如果我输入(5+2),计算器将返回2作为答案,如果我再次按下等号,它将返回5作为答案。如果我输入(5*2)+(3*9),它会返回9作为答案,如果我再次按下等号,它会将5作为asnwer返回。我试过多次检查我的代码,但不幸的是,我没能找到我的错误。如有任何帮助,我们将不胜感激!
免责声明:我知道关于使用String Tokenizer的附带说明。我会使用其他东西,但这是要求之一。我还没有实现任何错误检查或优先级检查,因为我想确保它在假设输入正确且不过于复杂的情况下正确工作。此外,我知道我的代码无法正确处理(5+2)-1之类的内容,因为1周围缺少括号。但话说回来,它无法与比这更简单的东西一起工作,所以……一旦我能让它与更简单的输入一起工作,我就会担心这一点。最后,这确实是一项家庭作业,但请不要认为我希望这完全是为我完成的。只要几点建议,我们将不胜感激。
这是我的代码:
public class ExpressionEvaluator {
Stack<String> myStack = new Stack<>();
Queue<String> myQueue = new Queue<>();
String curToken; //Current token of my tokenized string.
double temp1; //Place holder for first value of the calc section.
double temp2; //Place holder for second value of the calc section.
public String processInput(String s) {
StringTokenizer st = new StringTokenizer(s);
while (st.hasMoreTokens()) {
curToken = st.nextToken();
if (openParenthesis(curToken)) {
myStack.push(curToken);
}
if (closeParenthesis(curToken)) {
do {
myQueue.enqueue(myStack.pop());
} while (!openParenthesis(myStack.peek()));
}
if (isOperator(curToken)) {
while (!myStack.isEmpty() && !openParenthesis(myStack.peek())) {
myQueue.enqueue(myStack.pop());
}
myStack.push(curToken);
}
if (isDouble(curToken)) {
myQueue.enqueue(curToken);
}
}
while (!myStack.isEmpty()) {
myQueue.enqueue(myStack.pop());
}
while (!myQueue.isEmpty()) {
if (isDouble(myQueue.peek())) {
myStack.push(myQueue.dequeue());
}
else if (isOperator(myQueue.peek())) {
temp1 = Double.parseDouble(myStack.pop());
temp2 = Double.parseDouble(myStack.pop());
myStack.push(Double.toString(calc(temp1, temp2)));
}
else {
myQueue.dequeue();
}
}
return myStack.pop();
}
//Private methods used to simplify/clarify some things.
//Checks if input is an operator, returns true if it is
private boolean isOperator(String str) {
if (str == "+") {return true;}
else if (str == "-") {return true;}
else if (str == "*") {return true;}
else if (str == "/") {return true;}
else if (str == "^") {return true;}
else {return false;}
}
//Checks if input is an open parenthesis "(", returns true if it is
private boolean openParenthesis(String str) {
if (str == "(") {return true;}
else {return false;}
}
//Checks if input is a close parenthesis ")", returns true if it is
private boolean closeParenthesis(String str) {
if (str == ")") {return true;}
else {return false;}
}
//Checks if input is a double, returns true if it is
//I actually got this method from Stack Overflow, so thanks!
private boolean isDouble(String str) {
try {
Double.parseDouble(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
//Method used to actually do the calculations. I have
//a feeling this is where my problem is, but I can't
//think of a way to fix it.
private double calc(double a, double b) {
String op = myQueue.dequeue();
if (op == "+") {return a+b;}
else if (op == "-") {return a-b;}
else if (op == "*") {return a*b;}
else if (op == "/") {return a/b;}
else if (op == "^") {return Math.pow(a, b);}
else {throw new UnknownElementException(null, "ERROR");}
}
}
抱歉出现了奇怪的缩进。如有任何帮助,我们将不胜感激!
有一个名为分路码的算法,它指定如何将中缀表示法转换为后置表示法(也称为"反向波兰表示法")。这样您就不必担心运算符的优先级了。
它使用一个队列和一个堆栈。基本上,当您遇到一个数字时,您会将其添加到队列中。当你遇到操作符时,你会把它们推到堆栈上。
你可以在这里找到详细的算法:调车场算法
一旦使用反向抛光符号,您就可以像这里描述的那样轻松地对其进行评估:Postfix评估算法
我终于想通了!我使用==而不是.equals()来比较isOperator、closeParenthesis和openParenthisis方法中的字符串。