In the past two days, we saw stack and queue. In the stack module, we found the Dijkstra double-stack arithmetic expression evaluation algorithm, which can be used to implement a calculator-type app.
Programming Language systems generally have built-in processing of arithmetic expressions, but how are they implemented internally? To understand this process, we can build a simple arithmetic expression processing mechanism on our own. Here we use the stack feature and the Dijkstra algorithm mentioned in this article.
Overview:
An arithmetic expression may be a number, or an expression consisting of a left brace, an arithmetic expression, an operator, another arithmetic expression, and a right brace. To simplify the problem, the arithmetic expression without parentheses is defined here. It explicitly illustrates the operands of all operators, in the form:
(1 + (2 + 3) * (4*5 )))
Ideas:
An expression consists of parentheses, operators, and operands. These entities are sent to the stack one by one from left to right in the following 4 cases:
1. Push the operand to the operand stack;
2. Press the operator into the operator stack;
3. Ignore the left parenthesis;
4. In case of right parenthesis, an operator is displayed, the required number of operands are displayed, and the result after the operation is pushed to the operand stack;
When the last right parenthesis is processed, only one value is left on the operand stack, which is the calculation result of the expression. This method is hard to understand, but it is easy to prove that it can calculate the correct value:
Every time an algorithm encounters a subexpression enclosed by a bracket and composed of an operator and two operands, it pushes the operation result of the operator and the operand into the operand stack. This result is like replacing the subexpression with this value in the input, so the result obtained by replacing the subexpression with this value is the same as that of the original expression. We can apply this rule repeatedly and get a final value.
For example:
(1 + (2 + 3) * (4*5 )))
(1 + (5*(4*5 )))
(1 + (5*20 ))
(1 + 100)
101
Code implementation:
Here I use C # To implement it. The final running result is exactly as expected and proves the correctness of this algorithm. The Code is as follows:
using System;using System.Collections.Generic;using System.Linq;namespace Evaluate{ class Program { static void Main(string[] args) { string testExpress = "(1+((2+3)*(4*5)))"; Console.WriteLine(Evaluate(testExpress)); } //DijkStra static double Evaluate(string express) { var expressChars = express.ToArray<char>(); Stack<char> ops = new Stack<char>(); Stack<double> vals = new Stack<double>(); if (express.Length > 0) { foreach (var opt in expressChars) { switch (opt) { case ‘+‘: case ‘-‘: case ‘*‘: case ‘/‘: ops.Push(opt); break; case ‘)‘: var op = ops.Pop(); var v = vals.Pop(); switch (op) { case ‘+‘: v += vals.Pop(); break; case ‘-‘: v = vals.Pop() - v; break; case ‘*‘: v *= vals.Pop(); break; case ‘/‘: v = vals.Pop() / v; break; } vals.Push(v); break; case ‘ ‘: case ‘(‘: break; default: vals.Push(double.Parse(opt.ToString())); break; } } return vals.Pop(); } return double.MaxValue; } }}
Summary:
The Dijkstra algorithm makes full use of the stack features and has high execution efficiency. After further expansion and modification, it can completely implement a complex computing app with scientific computing functions. If you still have better and more suitable algorithms, please give us the address in the comments. Thank you.
Algorithm Manual (2) Dijkstra double-stack arithmetic expression evaluate Algorithm