The introduction
Recently at the teacher han Shunping’s data structure: stack space to achieve a comprehensive calculator, the front of the realization of the idea of a calculator without parentheses, Han teacher has given: through the number stack and operator stack to deal with the formula… . For the subsequent optimization of the calculator, Han proposed the idea is to change the infix expression into a suffix expression to complete. However, I came up with a new idea: instead of changing the infix expression into the suffix expression, the formula in each parenthesis is regarded as the original formula only by recursion.
Thought analysis
Take a simple nested multi-layer algorithm: (2+1)+((2+1)+12))*2+40. This algorithm contains two cases:
- Nesting of parentheses:
((2 + 1) + 12)
, including2 + 1
is((2 + 1) + 12)
theThe child formula - A formulaMultiple parentheses are present inThe child formula, such as
((2 + 1) + (2 + 1) + (12))
In the2 + 1
andThe (2 + 1) + 12
It’s in the same bracket.
First compute the nested subexpression without nested parentheses, then replace the subexpression with the result of that subexpression, so as to obtain a new general expression, and then continue to compute the subexpression inside… . The actual steps are as follows:
-
((2 + 1) + (2 + 1) + (12)) * 2 + 2 + 1 is one of 40 children formula without parentheses, 2 + 1 = 3 is calculated, the calculated results of 3 replace 2 + 1, get the new formula (3 + (2 + 1) + (12)) * 2 + 40
-
(3 + (2 + 1) + (12)) * 2 + 2 + 1 is one of 40 children without parentheses formula, the calculated results 2 + 1 = 3 replacement, get new formula (3 + (3 +)) * 2 + 40
-
. Skip some steps…
The result is 18*2+40, which is an expression without parentheses. The expression is typed directly into a calculator that does not recognize parentheses, and the output is the final result
Note: a subroutine is the bracketed part of an expression. A subroutine is a multilevel relation: e.g2+1, (2+1) +12Is ((2+1A) + ((2+1) +12)),2+1Is ((2+1) +12).Copy the code
The function of the
calculateFormula(String formula)
:Calculator that does not recognize parentheses, enter an expression without parentheses, and return the resultcalculateAnyFormala(String formula)
:A calculator that recognizes parentheses, supports the input of parentheses and returns the result
The complete code
// Support calculator with parentheses
public static int calculateAnyFormala(String formula) {
if (formula.contains("(") || formula.contains(")")) {
// get the first '(; The index of the last ')' gets the next '(' and ')'
/* * analysis: if the next parenthesis is ')', the intercept position is: frist+1 ~ nextr, if the next parenthesis is '(', the intercept position is: frist+1 ~ last */
int frist = formula.indexOf("(");
int nextr = formula.indexOf(")", frist + 1);
int nextl = formula.indexOf("(", frist + 1);
int last = formula.lastIndexOf(")");
// Create a substring to get the subalgorithm
String subStr = "";
if (nextl == -1 || nextl < nextr) {
subStr = formula.substring(frist + 1, last);
} else {
subStr = formula.substring(frist + 1, nextr);
}
// Return the result of this function, so as to get a new formula
int result = calculateAnyFormala(subStr);
StringBuilder sb = new StringBuilder("(");
sb.append(subStr);
sb.append(")");
formula = formula.replace(sb.toString(), String.valueOf(result));
return calculateAnyFormala(formula);
} else {
returncalculateFormula(formula); }}Copy the code
// no calculator with parentheses
public static int calculateFormula(String formula) {
// Convert to array, regardless of other irrelevant characters in the formula, and the formula input is correct
char[] charArray = formula.toCharArray();
// Initializes the memory space of the numeric stack and character stack
numStack = new ArrayStack(charArray.length);
operatorStack = new ArrayStack(charArray.length);
// Add data to numeric stack and character stack respectively according to the operation rules
/* * 1; /* * 1; /* * 2; If the priority is less than or equal to the previous operator, then the previous operator may be multiplication and division, which needs to be calculated immediately * note: ArrayStack can store only int data, so calling getOperator requires a strong */
StringBuilder sb = new StringBuilder();
for (int i = 0; i < charArray.length; i++) {
Operator element = Operator.getOperator(charArray[i]);
if (element == null) {
sb.append(charArray[i]);
} else {
// The number is pushed directly into the stack
numStack.push(Integer.parseInt(sb.toString()));
sb = new StringBuilder();
// Judge the operator
if((! operatorStack.isEmpty()) || element.level > Operator.getOperator((char) operatorStack.topElement()).level) {
operatorStack.push(charArray[i]);
} else {
int firstNum = numStack.pop();
int secondNum = numStack.pop();
// Calculate the provisional result
int tempResult = calculateTwoNum(secondNum, firstNum,
Operator.getOperator((char) operatorStack.pop()));
/ / the new stacknumStack.push(tempResult); operatorStack.push(charArray[i]); }}}// The last possible case is a+b; A +b*c does not end with a number a+b+ -> c+; a+d*
numStack.push(Integer.parseInt(sb.toString()));
int count = operatorStack.getTop();
for (int i = 0; i <= count; i++) {
int firstNum = numStack.pop();
int secondNum = numStack.pop();
int tempResult = calculateTwoNum(secondNum, firstNum, Operator.getOperator((char) operatorStack.pop()));
numStack.push(tempResult);
}
return numStack.pop();
}
Copy the code
Link to data structure course by Han Shunping
www.bilibili.com/video/BV1E4…