您的位置:首页 > 其它

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

2009-05-11 13:05 260 查看
注:此代码只能完成简单的加减乘除四则运算,但是不支持单目运算,更复杂的形式留待以后有时间再进一步完善。
 
 
#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; //栈对象定义,用于后缀表达式的计算过程,存储操作数
    
4000
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  存储