我正在尝试创建一个程序,它将使用堆栈为类的项目计算表达式。我还没有完成它,我只是想要进入两个堆栈之一,一个运算符堆栈和一个操作数堆栈。一切都按照我预期的方式工作,直到我创建了一个方法来检查运算符堆栈的优先级,它是如何工作的,加号和减号具有最低优先级然后它是乘法和除法符号和大于或等于符号具有最高优先级。我的代码中的这个方法叫做checkPred,当这个方法被注释掉时,我的JFile Chooser工作并从文件中读取数据但是当它没有被注释掉时我的JFile Chooser不起作用并且在我的try / catch语句中它执行了catch块导致输出Error!。我正在阅读的.txt文件包含:4 * 6 * 5-9
import java.io.*;
import java.util.*;
import javax.swing.JFileChooser;
public class Evaluate
{
static Stack<Character> operators = new Stack<Character>();
static Stack<Character> operands = new Stack<Character>();
public static void main(String args[])
{
JFileChooser chooser = new JFileChooser();
int status;
status = chooser.showOpenDialog(null);
if(status == JFileChooser.APPROVE_OPTION)
{
try
{
FileReader reader = new FileReader(chooser.getSelectedFile().getAbsolutePath());
BufferedReader buff = new BufferedReader(reader);
String line;
while((line = buff.readLine()) != null)
{
getCharAt(line);
}
buff.close();
}
catch(Exception ex)
{
System.out.println("Error!");
}
}
else
{
System.out.println("Open File dialog canceled");
}
}
public static void getCharAt(String x)
{
int charToInt;
for(int i = 0; i < x.length(); i++)
{
charToInt = x.charAt(i);
if(charToInt >= 48 && charToInt != 60 && charToInt != 62 )
{
operands.push(x.charAt(i));
}
else
{
if(checkPred(x.charAt(i),operators.peek()))
{
operators.push(x.charAt(i));
}
}
}
System.out.println(operands);
System.out.println(operators);
}
public static boolean checkPred(char op1, char op2)
{
int plusMinus = 1;
int multDivide = 2;
int greaterLess = 3;
int op1Value = 0;
int op2Value = 0;
if(op1 == 43 || op1 == 45)
{
op1Value = plusMinus;
}
else if(op1 == 42 || op1 == 47)
{
op1Value = multDivide;
}
else if(op1 == 60 || op1 == 62)
{
op1Value = greaterLess;
}
if(op2 == 43 || op2 == 45)
{
op2Value = plusMinus;
}
else if(op2 == 42 || op2 == 47)
{
op1Value = multDivide;
}
else if(op2 == 60 || op2 == 62)
{
op2Value = greaterLess;
}
if(op1Value > op2Value)
return true;
else
return false;
}
}
答案 0 :(得分:0)
查看代码的这一部分:
if(checkPred(x.charAt(i),operators.peek()))
{
operators.push(x.charAt(i));
}
在您的第一个运算符(第一个&#39; *&#39;)operators.peek()
在operators.push()
被调用一次之前的条件中调用。
这会导致EmptyStackException
被主方法中的catch块捕获。
答案 1 :(得分:0)
您可以使用此代码替换要添加operators
的部分。否则,当您第一次调用checkPred
方法时,operators
堆栈中没有任何内容可以查看。
if (operators.empty()) {
operators.push(x.charAt(i));
} else if (checkPred(x.charAt(i), operators.peek())) {
operators.push(x.charAt(i));
}
答案 2 :(得分:0)
JFile选择器或缓冲读卡器没有任何问题。导致问题的原因是在调用operators.push()之前,您需要填充操作数堆栈,否则会抛出异常。
我不确定你将如何完成这个计算器程序,但如果你需要第一次检查优先级,你可以这样做:
首先在运算符堆栈中添加一个元素,以后不再使用的任何字符,如:
operators.push('@'); // @ = 64 in ascii
补充checkPred(char,char)方法,比较'any operator'和@将始终产生'any运算符'具有更高的优先级。你可以这样开始你的方法:
public static boolean checkPred(char op1, char op2){
if (op1 == 64) return false;
if (op2 == 64) return true;
最后一件事,我不是ASCII大师,我需要查找你正在使用的每个角色的值。如果你将字符转换为整数然后将它们放在if语句中(或使用// 43 ='+'之类的注释),它会使你的代码更具可读性,当你看这个程序时它也会更加清晰再过几个星期,几个月的时间。