Это для оценки строковых выражений.Поэтому я использую этот сайт для создания сложного выражения со многими круглыми скобками, а когда их слишком много, он разрывается с исключением IndexOutOfBoundsException.https://dshepsis.github.io/ExpressionGenerator/ Я использую стеки и рекурсию для работы с круглыми скобками.Я указал строку, которую она прерывает в качестве комментария. Вот мой код:
private static float evaluate() { //No arguments to make recursion easier
Stack<Character> opStack = new Stack<Character>();
Stack<Character> currentOp = new Stack<Character>();
ArrayList<Float> numbers = new ArrayList<Float>();
//keep track of parenthesis
int indexOpen = 0, indexClose = 0, numOpen = 0, numClose = 0;
String newExpr;
String temp;
float ans = 0;
int temp2 = 0;
char operation;
int first, second;
//remove spaces
exp = exp.replaceAll(" ", "");
exp = exp.replaceAll("\t", "");
exp += " ";
//go thru expression to count array brackets
for (int i = 0; i < exp.length(); i++) {
if ( exp.charAt(i) == '[') {
indexOpen = i;
i++;
for (; i < exp.length(); i++){
if ( exp.charAt(i) == ']'){
numClose++;
}
if (exp.charAt(i) == '['){
numOpen++;
}
if ( exp.charAt(i) == ']' && numOpen < numClose){
indexClose = i;
numOpen = 0;
numClose = 0;
break;
}
}
newExpr = exp; //if theres parenthesis create subexpression
exp = exp.substring(indexOpen+1, indexClose);
temp = newExpr.substring(indexOpen, indexClose+1);
temp2 = temp.length();
temp = "" + (int)evaluate(); //recurse with the subexpression (arrays) hence cast to int
exp = newExpr.substring(0, indexOpen+1) + temp
+ newExpr.substring(indexClose, newExpr.length());
i-=temp2 - temp.length();
}
}
//do it again for regular parenthesis
for (int i = 0; i < exp.length(); i++) {
if ( exp.charAt(i) == '(') {
indexOpen = i;
i++;
for (; i < exp.length(); i++){
if ( exp.charAt(i) == ')'){
numClose++;
}
if (exp.charAt(i) == '('){
numOpen++;
}
if ( exp.charAt(i) == ')' && numOpen < numClose){
indexClose = i;
numOpen = 0;
numClose = 0;
break;
}
}
newExpr = exp;
exp = exp.substring(indexOpen+1, indexClose);
temp = newExpr.substring(indexOpen, indexClose+1);
temp2 = temp.length();
temp = "" + evaluate(); //same as above
exp = newExpr.substring(0, indexOpen) + temp
+ newExpr.substring(indexClose+1, newExpr.length());
i -= temp2 - temp.length();
}
}
opStack = getStackOps(exp);
numbers = getNumbers(exp);
if ( opStack.isEmpty() ){
return numbers.get(0);
}
int test = opStack.size(); //do the operations
for (int x = 0; x < test; x++){
operation = opStack.pop();
currentOp.push(operation);
if ( hasPriority(operation, opStack ) ) { //check PEMDAS
first = currentOp.size()-1;
second = currentOp.size();
//breaks at this line in the output below
ans = operate(numbers.get(first) , numbers.get(second), operation);
numbers.set(first, ans);
numbers.remove(second);
currentOp.pop();
}
else {
operation = opStack.pop();
currentOp.push(operation);
first = currentOp.size()-1;
second = currentOp.size();
//Do the ops
//breaks here sometimes also
ans = operate(numbers.get(first) , numbers.get(second), operation);
numbers.set(first, ans);
numbers.remove(second);
currentOp.pop();
opStack.push( currentOp.pop() );
}}
return ans;
}
Вот пример вывода:
Я могу предоставить вспомогательные методы operate and hasPriority
, если это необходимобыть.Я сделал много отладки, но я не могу понять, почему он ломается, когда есть много скобок.Спасибо за любую помощь:)