利用栈对表达式求值
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="js.js"></script> </head> <body> 输入中缀表达式空格分隔 例如 2 + 3 <input type="text" id="input" value=""><input type="button" onclick="fun()" value="计算"> <div id="aa"> </div> <script> /* * * #Re:【js数据结构】栈解决括号不匹配问题 * *一个算术表达式的后缀表达式形式如下: op1 op2 operator *使用两个栈,一个用来存储操作数,另外一个用来存储操作符,设计并实现一个 JavaScript 函 数,该函数可以将中缀表达式转换为后缀表达式,然后利用栈对该表达式求值。 */ function Stack() { this.top = 0; this.arr = []; this.push = push; this.pop = pop; this.peek = peek; this.clear = clear; this.len = len; this.isEmpty = isEmpty; } function push(val) { this.arr[this.top++] = val; } function pop() { return this.arr[--this.top]; } function peek(){ return this.arr[this.top-1]; } function clear(){ delete this.arr; this.top = 0; this.arr = []; } function len(){ return this.top; } function isEmpty() { if(this.len() <= 0) return true; else return false; } function operatorFun(result, val, operator) { switch (operator) { case "+": return parseInt(result) + parseInt(val); break; case "-": return result - val; break; case "*": return result * val; break; case "/": return result / val; break; } } var numStack = new Stack(); var operatorStack = new Stack(); function fun() { var Str = document.getElementById("input").value; strline = Str.split(" "); for(var i = 0; i<strline.length; i++) { if(i%2 == 0) numStack.push(strline[i]) else operatorStack.push(strline[i]) } var op, operator, result; if(numStack.len()>0) result = numStack.pop() while(numStack.len()>0 && operatorStack.len()>0) { operator = operatorStack.pop(); op = numStack.pop(); result = operatorFun(result, op, operator) } console.log(result) } </script> </body> </html>
展示如下:
顺序从右向左,无优先级顺序,图中顺序 4*5=20, 20+4=24,结果为24
考虑优先级的运算表达式求值
以上为不考虑优先级的表达式求值方法,那么接下来考虑优先级时,将考虑:
- 先乘除
- 后加减
- 有括号先算括号里
换成编程思路:
执行表达式运算时,总是将结果压入numStack栈
1. 遇到 “+”、“-” 操作符时,优先级最低,先计算栈内已存数据的加减乘除操作
2. 遇到 “*” 、“/” 操作符时,计算栈内已存数据的乘除操作
3. 遇到 “(” 直接入operatorStack
4. 遇到 “)” 运算栈内的数据,直到找到 “(”
代码如下:
function operatorFun(numStack, operatorStack) { var op1, op2, operator; op1 = numStack.pop(); op2 = numStack.pop(); operator = operatorStack.pop(); switch (operator) { case "+": numStack.push(parseInt(op2) + parseInt(op1)); break; case "-": numStack.push(op2 - op1); break; case "*": numStack.push(op2 * op1); break; case "/": numStack.push(op2 / op1); break; } }
function fun() { var Str = document.getElementById("input").value; strline = Str.split(" "); for(var i = 0; i<strline.length; i++) { if(strline[i] == "") { continue; } else if(strline[i] == "+" ||strline[i] == "-") { while((operatorStack.len() !=0 ) && (operatorStack.peek() == "+" || operatorStack.peek() == "-"|| operatorStack.peek() == "*" ||operatorStack.peek() == "/")) { operatorFun(numStack,operatorStack); } operatorStack.push(strline[i]) } else if(strline[i] == "*" ||strline[i] == "/") { while((operatorStack.len() !=0 ) && (operatorStack.peek() == "*" ||operatorStack.peek() == "/")) { operatorFun(numStack,operatorStack); } operatorStack.push(strline[i]) } else if(strline[i] == "(" ) { operatorStack.push('(') } else if(strline[i] == ")" ) { while(operatorStack.peek() != "(") { operatorFun(numStack,operatorStack); } operatorStack.pop(); } else { numStack.push(strline[i]) } } while(operatorStack.len() != 0) { operatorFun(numStack,operatorStack); } console.log(numStack.pop()) ; }
例如:计算 3 * 3 - ( 12 + 3 * 2 ) / 3
欢迎补充。