Algorithms and examples for parsing four arithmetic expressions in javascript, and four arithmetic operations in javascript
When writing code, we sometimes encounter the need to parse four arithmetic expressions by ourselves. This article briefly introduces how to use JavaScript to parse simple four arithmetic expressions.
1. Familiar with concepts
Infix notation(Or infix) is a general expression of arithmetic or logical formulas. An operator is in the middle of an operand in the form of infix (for example, 3 + 4 ). That is, our most commonly used arithmetic expressions. The infix expression is easier for humans to understand, but not for computer parsing.
Reverse Polish notation(Reverse Polish notation, RPN, or inverse Polish notation) is a mathematical expression introduced by the Polish mathematician Yang wukasevich in 1920. In the inverse Polish notation, all operators are placed after the operands, so they are also called suffix notation. Brackets are not required to mark the operator priority in the inverse Polish notation. The reverse Polish notation is easy to use the stack structure to parse and calculate the expression. Therefore, here We parse four element expressions, which are first converted from the infix expression to the reverse polish expression. Then calculate the value.
Ii. conversion process
Infix expression to suffix expression (Scheduling Algorithm)
1. Enter a mark in the queue.
2. If the mark is a number, add it to the output queue.
3. if it is an operator (+-*/), compare it with the top-stack operator in the output stack. If the priority is smaller than or equal to the top-stack operator, then, the operator at the top of the stack is popped up and added to the output queue (loop until the above conditions are not met), and the operator is pushed to the stack.
4. Press the left bracket into the stack.
5. If it is a right brace, the operator is constantly popped up from the stack and added to the output queue, knowing that the element at the top of the stack is a left brace. Left brackets are displayed, and no output queue is added. If no left brackets are found, the brackets in the original expression are asymmetrical and incorrect.
6. If the input queue is empty and there is still an operator in the stack, if the operator at the top of the stack is left parenthesis, the original expression contains mismatched parentheses. Add the operators in the stack to the output queue one by one.
7. Complete
Iii. Code Conversion
function isOperator(value){var operatorString = "+-*/()";return operatorString.indexOf(value) > -1}function getPrioraty(value){switch(value){case '+':case '-':return 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. Evaluate the inverse polish expression
1. A mark is displayed from the input queue.
2. If it is an operand, add it to the output stack.
3. If it is an operator, two operands are popped up from the output stack for calculation, and the calculated value is pushed into the output stack.
4. loop operation. If the input queue is empty and there is only one number in the output stack, this number is returned. Otherwise, redundant operands are displayed.
5. computing code
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];}}
Vi. Conclusion
I am not very familiar with the reverse Polish notation when I first came into contact with it. But after I became familiar with it, I found that the idea was actually very simple. Unlike the infix notation, there were various priorities, and parentheses, the logic is particularly troublesome. It is still relatively simple to use the reverse Polish notation, and there is no need to consider the priority or parentheses at all.
Design a demo program to implement four arithmetic expressions and values
/* What is the demo program? This is our job. It is rough to calculate the suffix of the suffix. I don't know if it is not. I hope it will be useful to you */
/******* A top_temp pointer is added to the stack in this program to traverse the stack from the bottom of the stack ********/
# Include <stdio. h>
# Include <malloc. h>
# Include <stdlib. h>
# Define INITSIZE 10
# Define SIZE 100
# Define OK 1;
# Define ERROR 0;
Typedef struct {
Int oator;
Char orand;
} SElemType;
Typedef struct {
SElemType * base;
SElemType * top;
SElemType * top_temp;
Int stacksize;
} SqStack;
Int InitStack (SqStack * S)
{
S-> base = (SElemType *) malloc (SIZE * sizeof (SElemType ));
If (! S-> base) exit (0 );
S-> top_temp = S-> top = S-> base;
S-> stacksize = SIZE;
Return OK;
}
Int Push_oator (SqStack * S, int Oat) // Insert the top element of the stack algorithm, integer
{
If (S-> top-S-> base> = SIZE)
{
S-> base = (SElemType *) realloc (S-> base, INITSIZE * sizeof (SElemType ));
S-> top = S-> base + S-> stacksize;
S-> stacksize + = INITSIZE;
}
S-> top-> oator = Oat;
S-> top-> orand = 0;
S-> top ++;
Return OK;
}
Int Push_orand (SqStack * S, char Orand) // Insert the top element of the stack, character type
{
If (S-> top-S-> base> = SIZE)
{
S-> base = (SElemType *) realloc (S-> base, INITSIZE * sizeof (SElemType ));
S-> top = S-> base + S-> stacksize;
S-> stacksize + = INITSIZE;
}
S-> top-> orand = Orand;
S-> top-> oator = 0;
S-> top ++;
Return OK;
}
Int GetTop (SqStack * S) // gets the top element of the stack. The returned value is the value of the top element of the stack.
{
If (S-> top = S-> base) exit (0 );
If (S-> top-1)-> oator = 0 & (S-> top-1)-> orand! = 0) // if it is an operator
Return (S-> top-1)-> orand; // return Characters
If (S-> top-1)-> oator! = 0 & (S-> top-1)-> orand = 0) // if it is an operator
Retu ...... remaining full text>
C ++ programming: Analysis and Calculation of four mixed operation expressions
Double PostCalculate: calculate (std: string * p, int size)
{
Std: stack <string>;
Std: string postExp [20];
Int count = 0; // count the suffix expression
For (int I = 0; I <size; I ++)
{
If (! IsSign (p) // if it is not a symbol, it is a number
{
PostExp [count] = * p; // put the number directly into the suffix expression
Count ++;
}
Else if (* p = "+" | * p = "-")
{
While (! A. empty () & a. top ()! = "(") // Pop up the elements in the stack until the stack is empty or left parentheses
{
PostExp [count] = a. top ();
Count ++;
A. pop ();
}
A. push (* p); // press the current element to stack
}
Else if (* p = "*" | * p = "/")
{
While (! A. empty () & a. top ()! = "(" & A. top ()! = "+" & A. top ()! = "-")
{
PostExp [count] = a. top ();
Count ++;
A. pop ();
}
A. push (* p );
}
Else if (* p = "(")
{
A. push (* p );
}
Else if (* p = ")")
{
While (! A. empty () & a. top ()! = "(")
{
PostExp [count] = a. top ();
Count ++;
A. pop ();
}
If (! A. empty () & a. top () = "(")
A. pop ();
}
P ++;
}
While (! A. empty ())
{
PostExp [count ++] = a. top ();
A. pop ();
}
Double result = postCal (postExp, count );
Return result;
}
Std: string PostCalculate: dispose (std: string first, std: string second, std: string op)
{
Stringstream t;
Double r;
Double a = stringToDouble (first );
Double B = stringToDouble (second );
If (op = "+ ")
R = a + B;
Else if (op = "-")
R = a-B;
Else if (op = "*")
R = a * B;
Else if (op = "/")
R = a/B;
T ...... remaining full text>