在这篇文章中,我们已经解释了如何使用堆栈评估算术表达式(如2*3+4)。我们介绍了算法和时间/空间复杂性。
内容表。
- 算术表达式的介绍
- 评估算术表达式的算法
- 一步一步的例子
- 实施
- 时间和空间复杂性
我们现在将直接进入这个问题。
算术表达式简介
算术表达式可以用3种形式表示。
- 英缀符号法
- 后缀符号法(反向波兰符号法
- 前缀符号法(波兰符号法
Infix记号的形式是 操作数1 操作符 操作符2
Eg: 5 + 3
后缀符号可以表示为_操作数1_ 操作数 2。
Eg: 5 3 +
前缀符号可以表示为操作数 1
操作数
2。
Eg: + 5 3
我们在日常工作中最经常使用infix符号。然而,机器发现infix符号比prefic/postfix符号更难处理。因此,编译器在表达式被评估之前将英缀符号转换为前缀/后缀。
操作符的优先级需要考虑到案例。
Exponentiation(^) >
Multiplication( * ) or Division(/) >
Addition(+) or Subtraction(-)
括号具有最高的优先级,它们的存在可以覆盖优先级顺序。
为了评估一个infix表达式,我们需要执行2个主要任务。
-
将infix转换为postfix
-
评估后缀
让我们逐一讨论这两个步骤。
关于步骤1,请参考这篇文章:使用Stack将infix转换为后缀表达式。
一旦表达式被转换为后缀符号,就可以执行步骤2。
评估算术表达式的算法
步骤。
-
遍历表达式:
1.1 如果字符是操作数,将其推入堆栈。
1.2 如果字符是操作数,从堆栈中取出最上面的两个元素并进行操作。将结果推回堆栈。 -
一旦表达式被完全遍历,堆栈中的元素就是结果。
一步一步的例子
第1步是将这个不定式表达式改为后缀:5 3 7 * +
第2步:堆栈S = [],遍历字符串:
5:操作数,推入堆栈,S = [5],top = 5
3:操作数,推入堆栈,S = [5, 3],top = 3
7。操作数,推入堆栈,S = [5, 3, 7], top = 7
* :操作符,弹出最上面的两个元素,op1=7,op2=3。 弹出操作后的堆栈S=[5],top=5。现在,我们将op1 * op2的结果,即7 * 3 = 21推入堆栈。S = [5, 21], top = 21
+ : 操作者,弹出最上面的两个元素,op1 = 21, op2 = 5。pop操作后的堆栈S = []。将op1 + op2的结果推入堆栈,即21 + 5 = 26,S = [26] 。
字符串已被完全遍历,堆栈只包含1个元素,即表达式=26的结果。
实施
在Java中实现。
public static int postfixEval(String str)
{
Stack<Integer> st = new Stack<>();
for(int i=0;i<str.length();i++)
{
char x = str.charAt(i);
if(x >= '0' && x <= '9')
{
st.push(Character.getNumericValue(str.charAt(i)));
}
else
{
int op1 = st.pop();
int op2 = st.pop();
switch(x)
{
case '+' : st.push(op2 + op1);
break;
case '-' : st.push(op2 - op1);
break;
case '*' : st.push(op2 * op1);
break;
case '/' : st.push(op2 / op1);
break;
}
}
}
return st.pop();
}
在C++中实现。
int postfix_eval(string str)
{
stack<int> st;
for(int i=0;i<str.length();i++)
{
char x = str[i];
if(isdigit(x))
{
st.push(x - '0');
}
else
{
int op1 = st.pop();
int op2 = st.pop();
switch(x)
{
case '+' : st.push(op2 + op1);
break;
case '-' : st.push(op2 - op1);
break;
case '*' : st.push(op2 * op1);
break;
case '/' : st.push(op2 / op1);
break;
}
}
}
return st.pop();
}
时间和空间复杂度
时间复杂度。O(N)
我们正好遍历整个字符串一次。另外,我们最多执行2n次推/拉操作,这意味着一个元素进入堆栈,又从堆栈中出来(n个元素的2n次操作)。这导致了时间复杂度为O(n)。
空间复杂度。O(N)
我们使用一个辅助堆栈,它最多可以包含N/2个元素。因此,该算法的空间复杂度为O(N)。
通过OpenGenus的这篇文章,你一定对使用堆栈的算术表达式评估有了完整的认识。