我遇到了一个问题,当我试图计算一个科学表达式时,它会编译但是当我运行它时会崩溃。我的程序的工作方式是它接收一个包含需要计算的数学表达式的字符串。首先,它分为包含数字和运算符的ArrayList。然后搜索任何括号,使程序首先使用括号内的表达式。然后它调用计算答案的计算。我一直收到的错误是“线程中的异常”AWT-EventQueue-0“java.lang.IndexOutOfBoundsExcepton:Index:0,Size:0”我认为它与我的arraylist大小有关但是,我无法发现错误,还有其他人可以帮我弄清楚吗?我相信问题最有可能是方法splitLabel和calculate
public ArrayList<String> splitLabel(String val){
ArrayList<String> label_split = new ArrayList<String>();
String value = "";
String op = "";
for (int i = 0; i< val.length(); i++){
boolean isDigit = Character.toString(val.charAt(i)).matches("[0123456789.]+");
boolean isOperator = Character.toString(val.charAt(i)).matches("[+*/^-]+");
boolean isSin = (Character.toString(val.charAt(i)).equals("s") && Character.toString(val.charAt(i+1)).equals("i") && Character.toString(val.charAt(i+2)).equals("n"));
boolean isCos = (Character.toString(val.charAt(i)).equals("c") && Character.toString(val.charAt(i+1)).equals("o") && Character.toString(val.charAt(i+2)).equals("s"));
boolean isTan = (Character.toString(val.charAt(i)).equals("t") && Character.toString(val.charAt(i+1)).equals("a") && Character.toString(val.charAt(i+2)).equals("n"));
boolean isOpBracket = Character.toString(val.charAt(i)).equals("(");
boolean isClBracket = Character.toString(val.charAt(i)).equals(")");
if (isOperator && !value.equals("")){
op = Character.toString(val.charAt(i));
label_split.add(value);
label_split.add(op);
op = "";
value = "";
} else if (isOperator && value.equals("")){
if (Character.toString(val.charAt(i)).equals("-")){
value = Character.toString(val.charAt(i));
}
} else if (isSin){
label_split.add("sin");
}else if (isCos){
label_split.add("cos");
}else if (isTan){
label_split.add("tan");
} else if (isOpBracket && !value.equals("")){
label_split.add(value);
label_split.add("(");
value = "";
} else if (isOpBracket && value.equals("")){
label_split.add("(");
} else if (isClBracket && !value.equals("")){
label_split.add(value);
label_split.add(")");
value = "";
}
if (i== val.length()-1 && !value.equals("")){
label_split.add(value);
} else if (i== val.length()-1 && Character.toString(val.charAt(i)).equals(")")){
label_split.add(")");
}
} return label_split;
}
public String bracket(ArrayList<String> label_split){
ArrayList<Integer> opBra = new ArrayList<Integer>();
ArrayList<Integer> clBra = new ArrayList<Integer>();
ArrayList<String> calculation = new ArrayList<String>();
int counter = 0;
int counter1 = 0;
if (label_split.contains("(") && label_split.contains(")")){
for (int j=0; j<label_split.size(); j++){
if (label_split.get(j).equals("(")){
counter = counter + 1;
opBra.add(j);
} else if (label_split.get(j).equals(")")){
counter1 = counter1 + 1;
clBra.add(j);
}
}
if (counter1 != counter){
return "error missing bracket";
} else {
for (int j=opBra.size(); j>0; j--){
int opBraPos = opBra.get(j) + 1; //+1 and -1 so it doesn't include ()
int clBraPos = clBra.get(opBra.size()-j) - 1;
opBra.remove(j);
clBra.remove(opBra.size()-j);
for(int t = 0; t < (clBraPos - opBraPos); t++){
calculation.add(label_split.get(t+opBraPos));
}
String value = calculate(calculation);
label_split.set(j , value);
calculation.clear();
for (int n = 0; n < ((clBraPos+1) - opBraPos); n++){
label_split.remove(n);
}
}
}
return calculate(label_split);
} else{
return calculate(label_split);
}
}
public String calculate(ArrayList<String> calculation){
double value = 0.0;
String value1 = "";
boolean isOperator = calculation.contains("[+*/^-]+");
boolean isSin = calculation.contains("sin"); //...ETC
for (int i=0; i < calculation.size(); i++){
if (calculation.get(i).equals("^") && i < calculation.size() && i < 0){
boolean isDigit1 = calculation.get(i-1).matches("[0123456789.-]+");
boolean isDigit2 = calculation.get(i+1).matches("[0123456789.-]+");
if (isDigit1 && isDigit2){
value = Math.pow(Double.parseDouble(calculation.get(i-1)), Double.parseDouble(calculation.get(i+1)));
value1 = Double.toString(value);
calculation.set(i,value1);
calculation.remove(i-1);
calculation.remove(i+1);
}
}
}
for (int a=0; a < calculation.size(); a++){
if ( (calculation.get(a)).equals("sin") && a < calculation.size() && a < 0){
boolean isDigit1 = calculation.get(a+1).matches("[0123456789.-]+");
if (isDigit1){
value = Math.sin(Double.parseDouble(calculation.get(a+1)));
value1 = Double.toString(value);
calculation.set(a,value1);
calculation.remove(a+1);
}
}
}
for (int b=0; b < calculation.size(); b++){
if ( (calculation.get(b)).equals("cos") && b < calculation.size() && b < 0){
boolean isDigit1 = calculation.get(b+1).matches("[0123456789.-]+");
if (isDigit1){
value = Math.cos(Double.parseDouble(calculation.get(b+1)));
value1 = Double.toString(value);
calculation.set(b,value1);
calculation.remove(b+1);
}
}
} // ETC
return calculation.get(0);
}
答案 0 :(得分:0)
这不是你的问题,但肯定是错的:
edtBarcode.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_ENTER)
|| keyCode == KeyEvent.KEYCODE_TAB) {
// handleInputScan();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (edtBarcode != null) {
edtBarcode.requestFocus();
}
}
}, 10); // Remove this Delay Handler IF requestFocus(); works just fine without delay
return true;
}
return false;
}
});
问题是calculation.set(i,value1);
calculation.remove(i-1);
calculation.remove(i+1);
会导致从remove(i-1)
开始的所有内容的索引减1。然后i
将删除之前位于索引remove(i+1)
的元素。
然后有这个:
i+2
想一想。如果for (int i=0; i < calculation.size(); i++){
if (calculation.get(i).equals("^") &&
i < calculation.size() &&
i < 0) {
从零开始并且递增到i
这是非负的,那么size()
怎么可能小于零。如果i
永远不会小于零,那么i
测试怎么能成功。 (你在其他地方重复这种模式。)
然而,真正的问题是以某种方式你在空列表上调用if
。
我认为是时候学会使用调试器.....