数据结构中栈的应用——中缀表达式的计算

该博客介绍了如何利用栈来计算中缀表达式的方法。首先,遇到数字时将其压入数栈;遇到'('时直接压入符栈;遇到')'时,从数栈取出两个数进行计算并重新压入数栈,直到符栈顶端元素为'(';对于其他操作符,依据优先级规则决定是否入栈或进行计算。最后,通过不断计算符栈中的操作符,得出数栈顶部元素即为计算结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/ /**基本思想 
    如果当前字符为数字 :则对其进行数字化(减去一个‘0’),然后将其压入数栈。
    如果当前字符为‘(’:则直接压入符栈。
    如果当前字符为‘)’:
      则从数栈中去顶部两个数,后一个作为左操作数进行计算,根据符栈中的操作符进行计算    
      并将结果重新压入数栈,循环此操作直至符栈顶端元素为‘(’,再将‘(’舍弃,
      在这种情况下无须考虑优先级,因为优先级的问题已经被下一种情况解决了。
    如果是其他操作符,则要进行优先级的比较:
      如果外部操作符的优先级 大于 符栈的当前操作符的优先级 或者 符栈为空,则操作符直接入栈
      否则
        当外部操作符的优先级 小于 符栈的当前操作符的优先级
        从栈中取两个操作数,后一个作为作操作数,
        根据符栈中的操作符进行计算并将结果重新保存到数栈中
        循环结束,还要将外部操作符入栈。
    最后根据符栈中的符号进行计算直到操作符栈为空,返回数栈的栈顶元素,也就是计算结果。
*/


//源代码

//Stack.cpp
const int SIZE=100;
//定义栈模板类
template <class T>
class Stack{
T data[SIZE];
int top;
public:
Stack()
{top=-1;};
~Stack(){}
bool isEmpty(){if(top==-1)return 1;return 0;}
void Push(T x);
T Pop();
T GetTop();
void Print();
}
;
//栈模板类的实现
template <class T>
void Stack<T>::Push(T x){
if(top==100)throw"上溢";
data[
++top]=x;
}

template 
<class T>
T Stack
<T>::GetTop(){
return data[top];
}

template 
<class T>
T Stack
<T>::Pop(){
if(top==-1)throw "下溢";
return data[top--];
}

template 
<class T>
void Stack<T>::Print(){
while(top!=-1)
   cout
<<data[top--];
}


//main.cpp
#include <iostream>
#include 
<string>
#include 
"Stack.cpp"
using namespace std;
int Rank(char a){//用于计算优先级
if(a=='(')
   
return 1;
else if(a=='+'||a=='-')
   
return 2;
else if(a=='*'||a=='/')
   
return 3;
}



Stack
<char> OPTR;
Stack
<double> OPND;//操作符和操作数栈

void Cal();//函数声明 用于计算
double Calculate(const string &s){
double result;
for(int i=0;i!=s.size();++i){
   
if(s[i]>='0'&&s[i]<='9'){
    OPND.Push(s[i]
-'0');
   }

   
else if(s[i]=='(')
    OPTR.Push(s[i]);
   
else if(s[i]==')')
   
{
    
while(OPTR.GetTop()!='(')
     Cal();
    OPTR.Pop();
   }

   
else
    
if(Rank(s[i])>Rank(OPTR.GetTop())||OPTR.isEmpty())
    OPTR.Push(s[i]);
    
else{
     
while(Rank(OPTR.GetTop())>=Rank(s[i])
      
&&!OPTR.isEmpty())
      Cal();
     OPTR.Push(s[i]);
    }

}

while(!OPTR.isEmpty())
   Cal();
result 
= OPND.Pop();
return result;
}

   
void Cal(){
double temp;
switch(OPTR.Pop()){
      
case '+':
       temp
=OPND.Pop();
       temp
=OPND.Pop()+temp;
       OPND.Push(temp);
break;
      
case '-':
       temp
=OPND.Pop();
       temp
=OPND.Pop()-temp;
       OPND.Push(temp);
break;
      
case '*':
       temp
=OPND.Pop();
       temp
=OPND.Pop()*temp;
       OPND.Push(temp);
break;
      
case '/':
       temp
=OPND.Pop();
       temp
=OPND.Pop()/temp;
       OPND.Push(temp);
break;
     }

}


int main(){
string exp;
cin
>>exp;
cout
<<exp<<'='<<Calculate(exp)<<endl;
system(
"pause");
return 0;
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值