Application of Javascript stack
Four arithmetic expressions, multiply and divide first and then add and subtract
//var x = '2+3*5-4';
1. Algorithm idea
Low-priority operator encounters its right-high-priority operator, and the right-hand side first calculates--------1 with the
same priority Operator, left-side precedence operation ------------ 2
High precedence operator encounters its right-low precedence operator, left-side precedence calculation-3
E.g
// 1+2+3;(2)
// 3+3
// 6
// 1+2*3(1)
// 1+6
// 7
// 1*2+3(3)
// 2+3
// 5
// 2+3*5-4-------------------(1)
// 2+15-4-------------------(2)
// 17-4--------------------(2)
// 13
// For each operator, only the priority of the following operator is higher than the current operator, follow the 1 principle, wait
// equal to, lower than, follow the 2 principle, and calculate directly
// 2. Software engineering ideas
// 2.1 Test cases produce limited but effective test cases,
//2+3*5-4
//1+2+3+4
//2*3*4*5
//1*2+3*4/2-4/2
//1+2
//2*3
//2.2 There must be debugging tools and means, debug tools, or log
// stack, push-pop
var x = '2+3*5-4';
var nArray = [];
var oArray = [];
var cl = 5;
var OPERATOR = [['+',0],['-',0],['*',1],['/',1]];
var nRet = 0;
var iRet = '';
var i = 0; //pointer to current op
//first number
var sNToken = x.charCodeAt(i) - 48;
var sPToken = '';
var nPriority = 0;
//'0' 30h 48 '9' 39h 57
if(sNToken < 0 || sNToken > 9){
iRet = 'Error at position ' + i + ' : is not a number(' + x.charAt(i) + ')! Are you kidding me?';
}else{
nArray.push(sNToken);//第一个数字压栈
i = 1;
for(;i<x.length;){
//get the operator
sPToken = x.charAt(i);
//-----validate the operator
for(var j = 0;j < OPERATOR.length;j++){
if(OPERATOR[j][0] == sPToken){
break;
}
}
if(j >=OPERATOR.length ){
iRet = 'Error at position ' + i + ' : Syntax error: invalid operator \'' + sPToken + '\'';
break;
}
//-----get the priority
nPriority = OPERATOR[j][1];
//get the second number
sNToken = x.charCodeAt(i+1) - 48;
if(sNToken < 0 || sNToken > 9){
iRet = 'Error at position ' + (i + 1) + ' : is not a number(' + x.charAt(i + 1) + ')! Are you kidding me?';
break;
}
//compare the priority of the operator
while(oArray.length !=0 && oArray[oArray.length-1][1] >= nPriority){
//弹栈计算
var n;
var n2 = nArray.pop();
var n1 = nArray.pop();
var op = oArray.pop()[0];
switch(op){
case '+':
n = n1 + n2;
break;
case '-':
n = n1 - n2;
break;
case '*':
n = n1 * n2;
break;
case '/':
n = n1 / n2;
break;
}
if(!isFinite(n) || isNaN(n)){
iRet = 'Error,the result is invalid!';
break;
}else{
nArray.push(n);
}
}
if(iRet){
break;
}
//压栈
nArray.push(sNToken);
var opPair=[];
opPair[0]=sPToken;
opPair[1]=nPriority;
oArray.push(opPair);
i+=2;
}
//compare the priority of the operator
while(oArray.length !=0){
//弹栈计算
var n;
var n2 = nArray.pop();
var n1 = nArray.pop();
var op = oArray.pop()[0];
switch(op){
case '+':
n = n1 + n2;
break;
case '-':
n = n1 - n2;
break;
case '*':
n = n1 * n2;
break;
case '/':
n = n1 / n2;
break;
}
if(!isFinite(n) || isNaN(n)){
iRet = 'Error,the result is invalid!';
break;
}else{
nArray.push(n);
}
}
}
//check
if(iRet){
console.log(iRet);
//Error happens-------------to be added------------------------
}else{
console.log(nRet=nArray.pop());
}