2. 一个算术表达式的后缀表达式形式如下:
op1 op2 operator
使用两个栈,一个用来存储操作数,另外一个用来存储操作符,设计并实现一个JavaScript函数,
该函数可以将中缀表达式转换为后缀表达式,然后利用栈对该表达式求值。
考虑优先级:
1.先乘除
2.后加减
3.有括号先算括号里
基本思路:为了完成算术表达式的计算,用到了两个栈,一个用于存放操作数,另一个用于存放操作符。
假设:程序中定义了两个栈:numStack(用来存放操作数)、operatorStack(用于存放操作符)。
在处理操作数和操作符之前,首先将它们压入栈中。当要处理一个操作符时,从operatorStack中将它弹出,
然后将它应用在来自numStack的前两个操作数上,得到的结果再压入numStack中。
实现的详细步骤:
1.扫描阶段:程序从左到右扫描表达式,提取操作数、运算符和括号。
1)如果提取的字符是一个操作数,将它压入numStack中。
2)如果提取的字符是一个+或-的运算符,因为+、-运算符在算术表达式中的优先级是最低的,所以此时在将+或者-运算符插入栈中之前,可以处理operatorStack栈顶的所有运算符,最后将提取出来的运算符压入operatorStack中。
3)如果提取的字符是一个*或/的运算符,则处理operatorStack栈顶的所有*和/的运算符,最后将新提取出来的运算符压入operatorStack中。
4)如果提取出来的运算符是一个"(",则将它压入operatorStack中。
5)如果提取出来的运算符是一个")",则重复处理operatorStack栈顶的运算符,直到看到栈顶的运算符为")"。
op1 op2 operator
使用两个栈,一个用来存储操作数,另外一个用来存储操作符,设计并实现一个JavaScript函数,
该函数可以将中缀表达式转换为后缀表达式,然后利用栈对该表达式求值。
考虑优先级:
1.先乘除
2.后加减
3.有括号先算括号里
基本思路:为了完成算术表达式的计算,用到了两个栈,一个用于存放操作数,另一个用于存放操作符。
假设:程序中定义了两个栈:numStack(用来存放操作数)、operatorStack(用于存放操作符)。
在处理操作数和操作符之前,首先将它们压入栈中。当要处理一个操作符时,从operatorStack中将它弹出,
然后将它应用在来自numStack的前两个操作数上,得到的结果再压入numStack中。
实现的详细步骤:
1.扫描阶段:程序从左到右扫描表达式,提取操作数、运算符和括号。
1)如果提取的字符是一个操作数,将它压入numStack中。
2)如果提取的字符是一个+或-的运算符,因为+、-运算符在算术表达式中的优先级是最低的,所以此时在将+或者-运算符插入栈中之前,可以处理operatorStack栈顶的所有运算符,最后将提取出来的运算符压入operatorStack中。
3)如果提取的字符是一个*或/的运算符,则处理operatorStack栈顶的所有*和/的运算符,最后将新提取出来的运算符压入operatorStack中。
4)如果提取出来的运算符是一个"(",则将它压入operatorStack中。
5)如果提取出来的运算符是一个")",则重复处理operatorStack栈顶的运算符,直到看到栈顶的运算符为")"。
2.清除栈阶段:重复处理来自operatorStack栈顶的运算符,直到operatorStack为空为止。
function operatorCge(numStack,operatorStack)
{
let op1,op2,operator;
op1=numStack.pop(); //取操作数的栈顶元素
op2=numStack.pop(); //取操作数的栈顶元素
operator=operatorStack.pop();//取操作符的栈顶元素
switch(operator)
{
case "+":
numStack.push(parseFloat(op2)+parseFloat(op1)); //将字符串转换成数字
break;
case "-":
numStack.push(op2-op1);
break;
case "*":
numStack.push(op2*op1);
break;
case "/":
numStack.push(op2/op1);
break;
}
}
function evaluateExpression(str){
let numStack=new Stack(); //存放操作数
let operatorStack=new Stack();//存放运算符
str=str.split("");
for(let i=0;i<str.length;i++)
{
if(str[i].trim()=="") //如果字符串为空,则跳过此次循环
{
continue;
}else if(str[i].trim()=="+"||str[i].trim()=="-")
{
//如果字符串为“+”或“-”,则执行栈中已存数据的加减乘除
while(!operatorStack.isEmpty() &&
( operatorStack.peek() == "+" ||
operatorStack.peek() == "-" ||
operatorStack.peek() == "*" ||
operatorStack.peek() == "/"
)){
operatorCge(numStack,operatorStack);
}
operatorStack.push(str[i]);
}else if(str[i].trim()=="*"||str[i].trim()=="/")
{
//如果字符串为“+”或“-”,则执行栈中已存数据的乘除计算
while(!operatorStack.isEmpty() &&
(operatorStack.peek() == "*" ||
operatorStack.peek() == "/"
)){
operatorCge(numStack,operatorStack);
console.log("*:",numStack.peek());
}
operatorStack.push(str[i]);
}else if(str[i].trim()=="(")
{ //如果遇到左括号,则将左括号压入操作符栈中
operatorStack.push(str[i]);
}else if(str[i].trim()==")")
{ //如果遇到右括号,则计算栈中的数据,直到遇到左括号为止
while(operatorStack.peek()!="(")
{
operatorCge(numStack,operatorStack);
}
operatorStack.pop();//将进行过计算的左括号弹出
}else
{ //如果遇到的是操作数,则将操作数直接压入操作数栈中
numStack.push(str[i]);
}
}
//对栈中数据进行计算,知道栈为空为止
while(!operatorStack.isEmpty())
{
operatorCge(numStack,operatorStack);
}
return numStack.pop();
}
let str="4+5-3*9-(2+ 3 )";
let result=evaluateExpression(str);
console.log(result);//-23