简单四则运算及表达式校验和转换工具类,仅供参考。
完整工具类请往我的//简单四则运算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$&"); } };