淘先锋技术网

首页 1 2 3 4 5 6 7

Javascript 栈的应用

四则运算式,先乘除后加减

//var x = '2+3*5-4';
1. 算法思路
低优先操作符遇到其右高优先级操作符,右侧先运算--------1
相同优先级的操作符,左侧优先运算------------2
高优先级操作符遇到其右低优先级操作符,左侧优先计算----3

例如

// 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

// 对于每一个操作符,只有后面的操作符的优先级,高于当前操作符,遵循1原则,等待
// 等于,低于,遵循2原则,直接计算
// 2. 软件工程思路
// 2.1测试用例产生有限但是有效的测试用例,

//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要有debug的工具和手段,debug工具,或者log

// 栈,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());
}