簡單四則運算及表達式校驗和轉換工具類,僅供參考。
完整工具類請往個人github項目bee.jsgit
//簡單四則運算 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$&"); } };