Arithmetic expression evaluation
One of the stack's use cases that we're going to learn is also a classic example of a generic application that is used to calculate the value of an arithmetic expression, such as
(1 + ((2 + 3) * (4 * 5 ) )
If you multiply 4 by 5, add 3 to 2, take their product and add 1, you get 101. But how does the Java system perform these operations? There is no need to study the construction details of a Java system, and we can write a Java program to solve this problem. It takes an input string (an expression) and outputs the value of the expression. To simplify the problem, first look at this explicit recursive definition: an arithmetic expression may be a number, or an expression consisting of an opening parenthesis, an arithmetic expression, an operator, another arithmetic expression, and a closing parenthesis. For simplicity, this is defined as an arithmetic expression that does not omit parentheses, which explicitly illustrates the operands of all operators--you may be more familiar with expressions like 1 + 2 * 3, omit parentheses, and use precedence rules. The simple mechanism we are going to learn can also handle priority rules, but here we don't want to complicate the problem. To highlight this, we support the most common two-tuple operators *, +,-and/, and the square root operator sqrt that accepts only one parameter. We can also easily support more numbers and kinds of operators to calculate a number of familiar mathematical expressions, including trigonometric, exponential, and logarithmic functions. Our focus is on how to interpret strings consisting of parentheses, operators, and numbers, and to do all sorts of primary arithmetic operations in the correct order. How can I get the value of an arithmetic expression (represented by a string)? In the 1960s, E.w.dijkstra invented a very simple algorithm, with two stacks (one for saving operators and one for saving operands) to complete this task, which is implemented as follows, and runs the trajectory as output.
An expression consists of parentheses, operators, and operands (numbers). We send these entities to the stack from left to right according to the following 4 scenarios:
- Pressing the operand into the operand stack
- To press an operator into the operator stack
- Ignore opening parenthesis
- When the parentheses are encountered, an operator pops up, pops up the desired number of operands, and presses the operator and operand results into the operand stack
After finishing the last closing parenthesis, there is only one value on the operand stack, which is the value of the expression. This approach is somewhat difficult to understand at first glance, but proving that it can calculate the correct value is simple: whenever the algorithm encounters a subexpression surrounded by parentheses and consists of an operator and two operands, it presses the calculation result of the operator and operand into the operand stack. The result is like using this value in the input instead of the subexpression, so the result of using this value instead of the subexpression is the same as the original expression. We can apply this rule over and over again and get a final value. For example, the algorithm evaluates the following expression to get the same result
(1 + ((2 + 3) * (4 * 5 ) )
(1 + ((5) * (4 * 5 )))
(1 + (5 * ))
(1 + )
101
Program:
1 Packagecom.beyond.algs4.experiment;2 3 ImportCom.beyond.algs4.lib.Stack;4 Importcom.beyond.algs4.std.StdIn;5 ImportCom.beyond.algs4.std.StdOut;6 7 Public classEvaluate {8 9 Public Static voidMain (string[] args) {Tenstack<string> Ops =NewStack<string>(); OneStack<double> Vals =NewStack<double>(); A //reads the character, and if it is an operator, presses it into the stack - while(!Stdin.isempty ()) { -String s =stdin.readstring (); the if(S.equals ("(")) ; - Else if(S.equals ("+") ) Ops.push (s); - Else if(S.equals ("-") ) Ops.push (s); - Else if(S.equals ("*") ) Ops.push (s); + Else if(S.equals ("/") ) Ops.push (s); - Else if(S.equals ("sqrt") ) Ops.push (s); + Else if(S.equals (")")) { A //if symbol is ")", popup operator and operand, calculate result and press into stack atString op =Ops.pop (); - Doublev =Vals.pop (); - if(Op.equals ("+")) v = vals.pop () +v; - Else if(Op.equals ("-")) v = vals.pop ()-v; - Else if(Op.equals ("*")) v = vals.pop () *v; - Else if(Op.equals ("/")) v = vals.pop ()/v; in Else if(Op.equals ("sqrt")) v =math.sqrt (v); - Vals.push (v); to } + ElseVals.push (double.parsedouble (s)); -Stdout.println ("Operand stack:" +vals.tostring ()); theStdout.println ("operator stack:" +ops.tostring ()); * } $ stdout.println (Vals.pop ());Panax Notoginseng } - the}
Output:
(1 + (2 + 3) * (4 * 5)) operand stack: operator stack: operand stack :1.0stack of operators: operand stacks:1.0operator Stacks:+operand stack:1.0operator Stacks:+operand stack:1.0operator Stacks:+operand stack:2.0 1.0operator Stacks:+operand stack:2.0 1.0operator Stacks:+ +operand stack:3.0 2.0 1.0operator Stacks:+ +operand stack:5.0 1.0operator Stacks:+operand stack:5.0 1.0operator Stacks:* +operand stack:5.0 1.0operator Stacks:* +operand stack:4.0 5.0 1.0operator Stacks:* +operand stack:4.0 5.0 1.0operator Stacks:* * +operand stack:5.0 4.0 5.0 1.0operator Stacks:* * +operand stack:20.0 5.0 1.0operator Stacks:* +operand stack:100.0 1.0operator Stacks:+operand stack:101.0operator Stacks:
Resources:
Algorithm fourth edition She Luyun algorithms Fourth Edition [US] Robert Sedgewick, Kevin Wayne
http://algs4.cs.princeton.edu/home/
SOURCE Download Link:
Http://pan.baidu.com/s/1c0Ao7Bi
"Algorithm" E.w.dijkstra Arithmetic expression evaluation