When writing code we sometimes encounter situations where we need to parse the arithmetic expression ourselves, this article simply describes using JavaScript to implement the parsing of simple arithmetic expressions.
First, familiar with the concept
infix notation (or infix notation) is a general method of arithmetic or logical formula representation, the operator is in infix form in the middle of the operand (example: 3 + 4). That is, our most commonly used arithmetic expression, infix expression for humans is relatively easy to understand, but not easy to computer parsing.
Counter-Polish notation (Reverse Polish NOTATION,RPN, or reverse Polish notation) is a mathematical expression introduced by the Polish mathematician Łukasiewicz 1920, in the reverse Polish notation, where all operators are placed behind the operand, It is also called the suffix notation. Counter Polish notation does not require parentheses to identify the precedence of an operator. Inverse Poland notation is easy to parse and compute an expression using a stack structure, so here we parse the four element expression, which is the first from the prefix expression to the inverse Polish expression. Then the value is computed.
Second, the conversion process
infix expression converted to suffix expression (dispatch field algorithm)
1. Input queue pops up a token
2. If the notation is a number, add it to the output queue
3. If it is an operator (+-*/), compare it with the operator on the top of the stack in the output stack, if the precedence is less than or equal to the operator at the top of the stack, the operator at the top of the stack is ejected and added to the output queue (looping until the above conditions are not met), and the operator is finally pressed onto the stack.
4. If it is an opening parenthesis, press into the stack
5. If it is a closing parenthesis, the constant popup operator from the stack, and add the output queue, know that the top element of the stack is an opening parenthesis. The opening parenthesis is ejected and does not join the output queue. If no opening parenthesis is found, the parentheses in the original expression are not known, and there is an error.
6. If the input queue is empty and the operator is still in the stack, if the operator on the top of the stack is an opening parenthesis, the original expression has an unmatched bracket. Eject the operator in the stack one by one and join the output queue.
7. Complete
III. Conversion Code Implementation
function Isoperator (value) {var operatorstring = ' +-*/() '; return Operatorstring.indexof (Value) >-1} function Getprioraty (value) {switch (value) {case ' + ': Case '-': RE
Turn 1;
Case ' * ': Case '/': return 2;
Default:return 0;
} function Prioraty (O1, O2) {return getprioraty (O1) <= getprioraty (O2);}
function DAL2RPN (exp) {var inputstack = [];
var outputstack = [];
var outputqueue = [];
for (var i = 0, len = exp.length i < len; i++) {var cur = exp[i];
if (cur!= ') {inputstack.push (cur);
} console.log (' Step One ');
while (Inputstack.length > 0) {var cur = inputstack.shift ();
if (Isoperator (cur)) {if (cur = = ' (') {outputstack.push (cur);
}else if (cur = = ") {var po = outputstack.pop ();
while (PO!= ' (' && outputstack.length > 0) {outputqueue.push (PO);
PO = Outputstack.pop ();
if (PO!= ' (') {throw "error:unmatched ()"; }else{while Prioraty (cur, OUTPUTSTACK[OUTPUTSTACK.LENGTH-1] && outputstack.length > 0) {outputqueue.push (Outputstack.pop ());
} outputstack.push (cur);
}}else{Outputqueue.push (new number (cur));
} console.log (' Step Two '); if (Outputstack.length > 0) {if (outputstack[outputstack.length-1] = = ') ' | | | outputstack[outputstack.length-1] = = ' (')
{throw "error:unmatched ()";
while (Outputstack.length > 0) {outputqueue.push (Outputstack.pop ());
} console.log (' Step Three ');
return outputqueue;
} console.log (Dal2rpn (' 1 + 2 '));
Console.log (DAL2RPN (' 1 + 2 + 3 '));
Console.log (DAL2RPN (' 1 + 2 * 3 '));
Console.log (DAL2RPN (' 1 + 2 * 3-4/5 '));
Console.log (DAL2RPN (' (1 + 2) '));
Console.log (DAL2RPN (' (1 + 2) * (3-4)/5 "); Console.log (DAL2RPN (1 + 2) * ((3-4)/5));
Iv. Counter-Polish expression evaluation
1. Eject a mark from the input queue
2. If the operand, add the output stack
3. If it is an operator, the two operands are popped from the output stack and calculated, and the computed values are pressed into the output stack.
4. Circular operation, if the input queue is empty, and the output stack has only one number of this number as the result, otherwise there is an extra operand.
V. Code of calculation
function Evalrpn (rpnqueue) {
var outputstack = [];
while (Rpnqueue.length > 0) {
var cur = rpnqueue.shift ();
if (!isoperator (cur)) {
outputstack.push (cur);
} else{
if (Outputstack.length < 2) {
throw "unvalid stack length";
}
var sec = Outputstack.pop ();
var fir = Outputstack.pop ();
Outputstack.push (GetResult (Fir, sec, cur));
}
if (outputstack.length!= 1) {
throw "unvalid expression";
} else{return
outputstack[0];
}
Six, the conclusion
Contrary to the Polish notation, it is not used to the first contact, but familiar, will find, in fact, the idea is particularly simple, not like infix notation, there are a variety of priorities Ah, as well as parentheses and so on, the logic is particularly troublesome, or reverse Polish notation is relatively concise, without considering the priority, there is no use of parentheses, Brackets and curly braces are aggravating.