表达式的计算(链栈表示)

注:此代码只能完成简单的加减乘除四则运算,但是不支持单目运算,更复杂的形式留待以后有时间再进一步完善。

 

 

#include "LinkedStack.h"

#include <cmath>

 

class Calculator

{

public:

     Calculator()

     {

         t.MakeEmpty();

         t.Push('#');  //栈底放一个'#'

     }

     void Run();   //执行表达式计算

     void Clear(); //清栈

private:

     void AddOperand(double value);   //操作数进栈

     bool Get2Operands(double & left,double & right);   //从栈中退出两个操作数

     void DoOperator(char op);   //形成运算指令,进行计算

     int isp(char ch);  //判断操作符的栈内优先数

     int icp(char ch);  //判断操作符的栈外优先数

     LinkedStack<double> s; //栈对象定义,用于后缀表达式的计算过程,存储操作数

     LinkedStack<char> t;   //栈对象定义,用于中缀表达式转后续表达式的过程,存储操作符

};

 

//读字符串并求一个后缀表达式的值,以字符'#'结束

void Calculator::Run()

{

     char ch,ch1,op;

     double newoperand;

     cin>>ch;

     while(1)

     {

         if(isdigit(ch))    //是操作数

         {

              //cout<<ch;

              cin.putback(ch);   //将字符放回输入流

              cin>>newoperand;   //重新读取操作数

              AddOperand(newoperand); //将操作数放入栈中

              cin>>ch; //读取下一扫描项

         }

         else

         {

              t.GetTop(ch1);     //取栈顶操作符ch1

              if (isp(ch1)<icp(ch))  //新输入操作符优先级高

              {

                   t.Push(ch);   //进栈

                   cin>>ch; //读取下一扫描项

              }

              else if (isp(ch1)>icp(ch))  //新输入操作符优先级低

              {

                   t.Pop(op);    //退栈

                   switch(op)

                   {

                   case '+':

                   case '-':

                   case '*':

                   case '/':

                       DoOperator(op);        //是操作符,执行计算

                       break;

                   }

              }

              else //输入操作符优先级等于栈顶优先级

              {

                   if(ch == '#')

                       break;

                   t.Pop(op);

                   if(op == '(')

                       cin>>ch;

              }

         }

     }

     assert(!s.IsEmpty());

     double temp;

     s.Pop(temp);

     cout<<"The result is:"<<temp<<endl;

}

 

//清栈

void Calculator::Clear()

{

     s.MakeEmpty();

}

 

//取两个操作数,根据操作符op形成运算指令并计算

void Calculator::DoOperator(char op)

{

     double left,right;

     bool result;

     result = Get2Operands(left,right);

     if(result == true)

     {

         switch(op)

         {

         case '+':

              s.Push(left+right);

              break;

         case '-':

              s.Push(left-right);

              break;

         case '*':

              s.Push(left*right);

              break;

         case '/':

              if(right == 0.0)

              {

                   cerr<<"Divided by 0!"<<endl;

                   Clear();

                   exit(0);

              }

              else

                   s.Push(left/right);

              break;

         }

     }

     else

         Clear();

}

 

//从操作数栈中取出两个操作数

bool Calculator::Get2Operands(double & left,double & right)

{

     if(s.IsEmpty())    //栈空

     {

         cerr<<"Missing Right Operand!"<<endl;

         return false;

     }

     s.Pop(right);

     if(s.IsEmpty())

     {

         cerr<<"Missing Left Operand!"<<endl;

         return false;

     }

     s.Pop(left);

     return true;

}

 

//将操作数的值value进操作栈

void Calculator::AddOperand(double value)

{

     s.Push(value);

}

 

int Calculator::isp(char ch)

{

     switch (ch)

     {

     case '#':

         return 0;

     case '(':

         return 1;

     case '*':

     case '/':

     case '%':

         return 5;

     case '+':

     case '-':

         return 3;

     case ')':

         return 6;

     }

     return -1;

}

 

int Calculator::icp(char ch)

{

     switch (ch)

     {

     case '#':

         return 0;

     case '(':

         return 6;

     case '*':

     case '/':

     case '%':

         return 4;

     case '+':

     case '-':

         return 2;

     case ')':

         return 1;

     }

     return -1;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值