这几天也在学习 JavaScript,前几日师傅给了一篇关于解析四则运算表达式和算法的文章,说四则运算很常用让我好好看看,再让编写代码看看最终结果。
首先我看了代码了解了两个关于算术或逻辑公式的表示法:中缀表示法以及逆波兰表示法,也学习了四则运算的实际转换过程(此定义在原文有详细解释)。
原文:http://www.jb51.net/article/53537.htm
然后我看了作者写的代码,自己分析看明白后,再加了些代码。在这个过程中巩固学习了关于堆栈的知识以及栈(后进先出)和队列(先进先出)方法。
以下代码就是自认为比较完整的代码:
http://www.gaodaima.com/30627.html
首先判断加减乘除的优先级,* 和 / 的优先级高于 + 和 - :
function isOperator(value) {
var operatorString = "+-*/()";
return operatorString.indexOf(value) > -1
}
function getPrioraty(value) {
switch (value) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}
//判断加减乘除的优先级
function prioraty(o1, o2) {
return getPrioraty(o1) <= getPrioraty(o2);
}
定义输入、输出栈以及输出队列,循环逐个添加到输入栈的末尾,之后处理符号和数字,当找到 "(" 和 ")" 时特殊处理:
function dal2Rpn(exp) {
//输入栈
var inputStack = [];
//输出栈
var outputStack = [];
//输出队列
var outputQueue = [];
for (var i = 0, len = exp.length; i < len; i++) {
var cur = exp[i];
if (cur != ' ') {
inputStack.push(cur); //+-*/() 数字,逐个添加到末尾
}
}
//处理字符和数字
while (inputStack.length > 0) {
//shift 顶部取得一项后移除,unshift 顶部推入
cur = inputStack.shift();
//如果是符号 --> + - * / ( )
if (isOperator(cur)) {
if (cur == '(') {
//push 从尾部推入一项
outputStack.push(cur);
} else if (cur == ')') {
//pop 从尾部取得一项,之后移出
var po = outputStack.pop();
while (po != '(' && outputStack.length > 0) {
outputQueue.push(po);
po = outputStack.pop();
}
if (po != '(') {
throw "错误:没有匹配";
}
} else { //符号时,处理 + - * /
while (prioraty(cur, outputStack[outputStack.length - 1])
&& outputStack.length > 0) {
outputQueue.push(outputStack.pop());
}
outputStack.push(cur);
}
} else { //是数字的时候,推入数字
outputQueue.push(new Number(cur));
}
}
if (outputStack.length > 0) {
if (outputStack[outputStack.length - 1] == ')'
outputStack[outputStack.length - 1] == '(') {
throw "错误:没有匹配";
}
while (outputStack.length > 0) {
outputQueue.push(outputStack.pop());
}
}
return evalRpn(outputQueue);
}
定义 evalRpn() 函数,输出堆栈的长度不小于2的时候,进行计算:
function evalRpn(queue) {
var outputStack = [];
while (queue.length > 0) {
var cur = queue.shift();
if (!isOperator(cur)) {
outputStack.push(cur);
} else {
//如果输出堆栈长度小于 2
if (outputStack.length < 2) {
throw "无效堆栈长度";
}
var second = outputStack.pop();
var first = outputStack.pop();
outputStack.push(getResult(first, second, cur));
}
}
if (outputStack.length != 1) {
throw "不正确的运算";
} else {
return outputStack[0];
}
}
进行加减乘除计算之后,对其值进行操作,当浮点数的小数位超过两位时,只保留两位小数点:
function getResult(first, second, operator){
var result = 0;
switch (operator) {
case '+':
result = first + second;
break;
case '-':
result = first - second;
break;
case '*':
result = first * second;
break;
case '/':
result = first / second;
break;
default:
return 0;
}
//浮点数的小数位超过两位时,只保留两位小数点
function formatFloat(f, digit) {
//pow(10,n) 为 10 的 n 次方
var m = Math.pow(10, digit);
return parseInt(f * m, 10) / m;
}
return (formatFloat(result, 2));
}
输入要计算的表达式,计算结果 ( 结果得到 -0.6 ):
var result=dal2Rpn('( 1 + 2 ) * (( 3 - 4 ) / 5)');
console.log(result); //输出结果
欢迎大家阅读《javaScript 四则运算:加减乘除_js》,跪求各位点评,若觉得好的话请收藏本文,by 搞代码
微信 赏一包辣条吧~
支付宝 赏一听可乐吧~