javaScript简单四则运算工具类ElementaryArithmeticUtils

ElementaryArithmeticUtils = {
		//运算符优先级
		operatorPrecedence: {
			'+': 0,
			'-': 0,
			'*': 1,
			'×': 1,
			'÷': 1,
			'\/': 1
		},
		//运算符
		operator: {
			'+': '+',
			'-': '-',
			'*': '*',
			'×': '*',
			'÷': '/',
			'\/': '/'
		},
		//加法
		add: function(operandLeft, operandRight) {
			var operand1 = operandLeft.toString();
			var operand2 = operandRight.toString();
			var decimalPlace1 = operand1.indexOf('.') >= 0 ? operand1.split('.')[1].length : 0;
			var decimalPlace2 = operand2.indexOf('.') >= 0 ? operand2.split('.')[1].length : 0;
			var multiple = Math.pow(10, Math.max(decimalPlace1, decimalPlace2));
			return(operandLeft * multiple + operandRight * multiple) / multiple;
		},
		//减法
		subtract: function(operandLeft, operandRight) {
			var operand1 = operandLeft.toString();
			var operand2 = operandRight.toString();
			var decimalPlace1 = operand1.indexOf('.') >= 0 ? operand1.split('.')[1].length : 0;
			var decimalPlace2 = operand2.indexOf('.') >= 0 ? operand2.split('.')[1].length : 0;
			var multiple = Math.pow(10, Math.max(decimalPlace1, decimalPlace2));
			//toFixed避免多出来小数位,如 11.3-10.12000=1.1800000000000015
			var decimalPlace = (decimalPlace1 >= decimalPlace2) ? decimalPlace1 : decimalPlace2;
			return((operandLeft * multiple - operandRight * multiple) / multiple).toFixed(decimalPlace);
		},
		//乘法
		multiply: function(operandLeft, operandRight) {
			var operand1 = operandLeft.toString();
			var operand2 = operandRight.toString();
			var decimalPlace1 = operand1.indexOf('.') >= 0 ? operand1.split('.')[1].length : 0;
			var decimalPlace2 = operand2.indexOf('.') >= 0 ? operand2.split('.')[1].length : 0;
			var multiple1 = Math.pow(10, decimalPlace1);
			var multiple2 = Math.pow(10, decimalPlace2);
			return((operandLeft * multiple1) * (operandRight * multiple2)) / Math.pow(10, decimalPlace1 + decimalPlace2);
		},
		//除法
		divide: function(operandLeft, operandRight) {
			var operand1 = operandLeft.toString();
			var operand2 = operandRight.toString();
			var decimalPlace1 = operand1.indexOf('.') >= 0 ? operand1.split('.')[1].length : 0;
			var decimalPlace2 = operand2.indexOf('.') >= 0 ? operand2.split('.')[1].length : 0;
			var multiple1 = Math.pow(10, decimalPlace1);
			var multiple2 = Math.pow(10, decimalPlace2);
			return((operandLeft * multiple1) / (operandRight * multiple2)) * Math.pow(10, decimalPlace2 - decimalPlace1);
		},
		//校验表达式的合法性
		isArithmeticExpression: function(expression) {
			try {
				expression = expression.replace(/÷/g, '/').replace(/×/g, '*');
				var result = eval(expression);
			} catch(e) {
				return false;
			}
			return true;
		},
		//计算
		calculate: function(expression) {
			var value = eval(expression);
			return value;
		},
		//中缀表达式转后缀表达式
		infixToPostfixExpression: function(expression) {
			expression = Bee.StringUtils.deleteWhitespace(expression);
			expression = this.eliminatePositiveOrNegativeSign(expression);
			var operatorStack = [];
			var resultStack = [];
			var elementArr = expression.match(/[-+\/÷*×()]|(?:[1-9]\d*|0)(?:\.\d+)?/g);
			var size = elementArr.length;
			for(var i = 0; i < size; i++) {
				if(Bee.StringUtils.isNumeric(elementArr[i])) {
					//如果是数值
					resultStack.push(elementArr[i]);
				} else {
					//操作符栈顶元素
					var operatorStackTopElement = operatorStack.length === 0 ? '' : operatorStack[operatorStack.length - 1];
					//运算符
					if(operatorStack.length === 0 || elementArr[i] === '(' || operatorStackTopElement === '(' || this.operatorPrecedence[elementArr[i]] > this.operatorPrecedence[operatorStackTopElement]) {
						//操作符栈为空或栈顶元素为右括号')',或操作符的优先级比栈顶运算符高或相等,直接入栈
						operatorStack.push(elementArr[i]);
					} else {
						//如果是右括号")",则依次弹出操作符栈顶的运算符,并压入结果栈,直到遇到左括号'('为止,左右括号不压入结果栈;
						if(elementArr[i] === ')') {
							for(var index = operatorStack.length - 1; index >= 0; index--) {
								if(operatorStack[index] === '(') {
									operatorStack.pop();
									break;
								} else {
									resultStack.push(operatorStack.pop());
								}
							}
						} else {
							//将符号栈顶的运算符弹出并压入到结果栈中,再次与符号栈中新的栈顶运算符相比较
							resultStack.push(operatorStack.pop());
							i--;
							continue;
						}
					}
				}
			}
			//处理操作符栈剩余的符号		
			if(operatorStack.length > 0) {
				for(var j = operatorStack.length - 1; j >= 0; j--) {
					resultStack.push(operatorStack.pop());
				}
			}
			//结果返回
			return resultStack.join(' ');
		},
		//中缀表达式转前缀表达式(结果以空格隔开)
		infixToPrefixExpression: function(expression) {
			expression = Bee.StringUtils.deleteWhitespace(expression);
			expression = this.eliminatePositiveOrNegativeSign(expression);
			var operatorStack = [];
			var resultStack = [];
			var elementArr = expression.match(/[-+\/÷*×()]|(?:[1-9]\d*|0)(?:\.\d+)?/g);
			var size = elementArr.length;
			for(var i = size - 1; i >= 0; i--) {
				if(Bee.StringUtils.isNumeric(elementArr[i])) {
					//如果是数值
					resultStack.push(elementArr[i]);
				} else {
					//操作符栈顶元素
					var operatorStackTopElement = operatorStack.length === 0 ? '' : operatorStack[operatorStack.length - 1];
					//运算符
					if(operatorStack.length === 0 || elementArr[i] === ')' || operatorStackTopElement === ')' || this.operatorPrecedence[elementArr[i]] >= this.operatorPrecedence[operatorStackTopElement]) {
						//操作符栈为空或栈顶元素为右括号')',或操作符的优先级比栈顶运算符高或相等,直接入栈
						operatorStack.push(elementArr[i]);
					} else {
						//如果是左括号"(",则依次弹出操作符栈顶的运算符,并压入结果栈,直到遇到右括号')'为止,左右括号不压入结果栈;
						if(elementArr[i] === '(') {
							for(var index = operatorStack.length - 1; index >= 0; index--) {
								if(operatorStack[index] === ')') {
									operatorStack.pop();
									break;
								} else {
									resultStack.push(operatorStack.pop());
								}
							}
						} else {
							//将符号栈顶的运算符弹出并压入到结果栈中,再次与符号栈中新的栈顶运算符相比较
							resultStack.push(operatorStack.pop());
							i++;
							continue;
						}

					}
				}
			}
			//处理操作符栈剩余的符号		
			if(operatorStack.length > 0) {
				for(var j = operatorStack.length - 1; j >= 0; j--) {
					resultStack.push(operatorStack.pop());
				}
			}
			//结果返回
			return resultStack.reverse().join(' ');
		},
		//解决正负号问题-1转为0-1;+1转为0+1
		eliminatePositiveOrNegativeSign: function(expression) {
			return expression.replace(/(\(|^)([-+])/g, '$10$2');
		},
		//把中缀表达式转为前缀表达式,再计算
		calculateByPrefixExpression: function(expression) {
			var elementArr = this.infixToPrefixExpression(expression).split(' ');
			var size = elementArr.length;
			var resultStack = [];
			for(var i = size - 1; i >= 0; i--) {
				if(Bee.StringUtils.isNumeric(elementArr[i])) {
					//如果是数值
					resultStack.push(elementArr[i]);
				} else {
					var operand1 = resultStack.pop();
					var operand2 = resultStack.pop();
					var result;
					switch(elementArr[i]) {
						case '+':
							result = Bee.ElementaryArithmeticUtils.add(operand1, operand2);
							break;
						case '-':
							result = Bee.ElementaryArithmeticUtils.subtract(operand1, operand2);
							break;
						case '×':
						case '*':
							result = Bee.ElementaryArithmeticUtils.multiply(operand1, operand2);
							break;
						case '\/':
						case '÷':
							result = Bee.ElementaryArithmeticUtils.divide(operand1, operand2);
							break;
						default:
							result = '';
							alert("The operator 【" + elementArr[i] + "】 is not legal");
							break;
					}
					resultStack.push(result);
				}
			}
			return resultStack;
		},
		//把中缀表达式转为后缀表达式,再计算
		calculateByPostfixExpression: function(expression) {
			var elementArr = this.infixToPostfixExpression(expression).split(' ');
			var size = elementArr.length;
			var resultStack = [];
			for(var i = 0; i < size; i++) {
				if(Bee.StringUtils.isNumeric(elementArr[i])) {
					//如果是数值
					resultStack.push(elementArr[i]);
				} else {
					var operand1 = resultStack.pop();
					var operand2 = resultStack.pop();
					var result;
					switch(elementArr[i]) {
						case '+':
							result = Bee.ElementaryArithmeticUtils.add(operand2, operand1);
							break;
						case '-':
							result = Bee.ElementaryArithmeticUtils.subtract(operand2, operand1);
							break;
						case '×':
						case '*':
							result = Bee.ElementaryArithmeticUtils.multiply(operand2, operand1);
							break;
						case '\/':
						case '÷':
							result = Bee.ElementaryArithmeticUtils.divide(operand2, operand1);
							break;
						default:
							result = '';
							alert("The operator 【" + elementArr[i] + "】 is not legal");
							break;
					}
					resultStack.push(result);
				}
			}
			return resultStack;
		},
		//横式计算
		horizontalCalculation: function(expression) {
			expression = Bee.StringUtils.deleteWhitespace(expression);
			expression = this.eliminatePositiveOrNegativeSign(expression);
			var result = expression;
			while(expression.indexOf('(') >= 0) {
				expression = expression.replace(/\([^()]+\)/g, function(matchStr) {
					return eval(matchStr);
				});
				result += '=' + expression;
			}
			while(expression.indexOf('[') >= 0) {
				expression = expression.replace(/\[[^\[\]]+\]/g, function(matchStr) {
					return eval(matchStr);
				});
				result += '=' + expression;
			}
			while(expression.indexOf('{') >= 0) {
				expression = expression.replace(/\{[^{}]+\}/g, function(matchStr) {
					return eval(matchStr);
				});
				result += '=' + expression;
			}
			var pattern = /(?:[1-9]\d*|0)(?:\.\d+)?[*/](?:[1-9]\d*|0)(?:\.\d+)?/;
			while(expression.indexOf('*') >= 0 || expression.indexOf('/') >= 0) {
				expression = expression.replace(pattern, function(matchStr, index) {
					return eval(matchStr);
				});
				result += '=' + expression;
			}
			if(/[-+*/]/.test(expression)) {
				result += '=' + eval(expression);
			}
			return result;
		},
		//竖式计算
		verticalCalculation: function(expression) {
			var result = this.horizontalCalculation(expression);
			return result.replace(/=/g, "\n$&");
		}
	};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值