/*** Expression Evaluator, enter a string of mathematical expressions, output the numeric value of the calculated result * 1. Scan the expression, respectively, into the stack with the operator and the operand, * 2. The operator prioritizes the previous operator before the stack, if the current operator priority is lower or equal to the previous operator, * The previous operator and the corresponding operand are stacked, otherwise the operator directly into the stack *@authorLijy*/ Public classExpressioncaculator {/*** Operational Arithmetic stack **/ Privatevar Numberstack:array; /*** operator Stack **/ Privatevar Operatorstack:array; /*** Constructor Function*/ Publicfunction Expressioncaculator () {}/*** Expression Evaluator * @expression expression *@returnevaluates, Nan represents a malformed or unsupported operator **/ Publicfunction Caculate (expression:string): number{//Remove Spacesvar Arr:array = expression.split (' '); Expression= ' '; forEach (var item:string in arr) {if(item!= ") expression+=item; } //Initialize StackNumberstack =NewArray (); Operatorstack=NewArray (); //traversing an expression for(Var i:int= 0; i<expression.length; i++) {var index:int=Getnextnumberendindex (expression,i); if(index>i) { //Get operation numbervar data:number = number (Expression.substr (i,index-i)); if(IsNaN (data)) {//incorrect expression returns nan returnNaN; }Else{ //arithmetic count into stackNumberstack.push (data); I=index-1; } }Else{ //gets the operator and calls out the stack operation Loopvar nextoperator:string = Expression.substr (i,1); var Success:boolean= This. Calculateloop (nextoperator)if(!success) { //Unsupported operator occurred during Operation returnNaN; }Else if(nextoperator!= ') '){ //operator in the stack, except for the right parenthesisOperatorstack.push (Nextoperator); } } } //finally call out the stack operation Loop, calculate the part that is not finishedvar Success:boolean = This. Calculateloop ()if(!success) { //Unsupported operator occurred during Operation returnNaN; }Else{ //return the result of the calculation returnNumberstack[0]; } } /*** out of stack operation Loop: * The operator before the loop out of the stack is compared with the operator of the next stack, * if the priority is higher than the next, the calculation is done, if the parentheses are the case, the parentheses merge or jump out of the calculation * @nex Toperator the next operator for the stack to be used to prioritize or remove parentheses from the previous operator *@returnThe calculation succeeds if there is an unsupported operator that will return Nan **/ Privatefunction Calculateloop (nextoperator:string= ') '): boolean{//Returns the result initial value: whether an unsupported operator existsvar result:boolean=true; //gets the priority of the next operatorvar nextpriority:number =getoperatorpriority (Nextoperator); //Enter the operation Loop while(operatorstack.length>0) {var lastoperator:string= Operatorstack[operatorstack.length-1]; var lastpriority:number=getoperatorpriority (Lastoperator); if(IsNaN (lastpriority) | |IsNaN (nextpriority)) { //An unsupported operator existsresult =false; Break; } if(Nextpriority >lastpriority) { //operators with precedence greater than previous do not operate, jumping out of loopsresult =true; Break; }Else if(lastoperator== ' ('){ //If the previous operator is an opening parenthesis://1. The next operator is the closing parenthesis, then the left and right brackets cancel, and the operator jumps out of the operation Loop//2. The next operator is not a closing parenthesis, then the left parenthesis is preserved, and the operation Loop if(nextoperator== ') ') Operatorstack.pop (); Result=true; Break; }Else{ //other cases outbound operations and loopsresult =popandcalculate (); if(result==false){ Break; } } } returnresult; } /*** The last operator of the stack and the corresponding operand is calculated, and the result of the operation is put into the stack *@returnoperation exception returns false, Normal returns True **/ Privatefunction Popandcalculate (): boolean{if(Numberstack.length<2 | | operatorstack.length<1){ //there must be at least two operands and an operator return false; }Else{var lastoperator:string=Operatorstack.pop () as String; var num1:number=Numberstack.pop () as number; var num2:number=Numberstack.pop () as number; Switch(lastoperator) { Case‘*‘: Numberstack.push (num2*NUM1); Break; Case‘/‘: Numberstack.push (num2/NUM1); Break; Case+: Numberstack.push (num2+NUM1); Break; Case‘-‘: Numberstack.push (num2-NUM1); Break; } return true; } } /*** Starting from the specified subscript position to get the next operand end of the subscript position, note the minus sign and minus sign * @expression expression * The starting subscript position of the @startIndex judgment * @returnSubscript position at the end of the next operand, if the return value equals startindex, the next character is the operator is not the operand **/ Private Staticfunction Getnextnumberendindex (expression:string, StartIndex:int):int{var i:int=StartIndex; //determines the minus and minus signs, the first character of the expression or the first character in front of the opening parenthesis if-, is the minus sign, otherwise a minus sign if(Expression.charat (i) = = '-'){ if(I==0 | | expression.charat (i-1) = = ' (') {i++; }Else{ returni; } } //traversing numbers and decimals for(i; i<expression.length; i++) {var ascii:number=expression.charcodeat (i); if((ascii>=48&&ascii<=57) | | | ascii==46){ Continue; }Else{ returni; } } returni; } /*** Get operator Precedence * @operator operator *@returnPriority Level **/ Private Staticfunction Getoperatorpriority (operator:string): number{Switch(operator) { Case‘(‘: return3; Case‘*‘: Case‘/‘: return2; Case+: Case‘-‘: return1; Case‘)‘: return0; default: returnNaN; } } }
Flex version of the stack-based expression evaluator