不错的思路,不错的设计(代码摘自殷人困数据结构书)

#include <iostream>
#include 
<stack>
using namespace std;
//模拟一个简单计算器,从键盘中读入后缀表达式

class Power
{
    
private:
        
double x;
        
int e;
        
double value;
    
public:
        Power(
double val,int exp);
        
double GetValue()const{return value;}
}

Power::Power(
double val,int exp)
{
    x
=val;
    e
=exp;
    value
=1.0;//这个初值在这里很重要,必须是1.0
    if(exp==0.0)
        
return;
    
else{
        
for(;exp>0;exp--)
            value
=value*x;
    }
}


class Calculator
{
    
public:
        Calculator(
int sz):s(sz){}
        
void Run();
        
void Clear();
    
private:
        
void AddOperator(double value);//操作数进栈
        bool GetTwoOperator(double&left,double&right);//从栈中退出两个操作数,一次退出两个
        void DoOperator(char op);//进行运算
        Stack<double> s;
};


void Calculator::AddOperator(double value)
{
    s.push(value);
}

//压栈的时候是按后缀就是先left后right
//弹栈的时候是按right后left
bool Calculator::GetTwoOperator(double&left,double&right)
{
    
if(s.isEmpty())
        
return false;
        
    right
=s.Pop();
    
    
if(s.isEmpty())
        
return false;
        
    left
=s.pop();
    
    
return true;
}


//注意这里的运算操作不是返回一个值,而是将结果压栈以便后面的操作,所以返回void类型而且也函数形参也不是引用类型
void Calculator::DoOperator(char op)
{
    
double left,right;
    
bool result;
    result
=GetTwoOperator(left,right);
    
if(!result)
        
this->Clear();//出现不正确的情况要做善后处理,不可以直接return了事
    else{
        
switch(op){
            
case'+':
                s.push(left
+right);
                
break;
                
            
case'-':
              s.push(left
-right);
              
break;
                
          
case'*':
                s.push(left
*right);
                
break;
                
            
case'/':
            
//error1:s.push(left/right);除法要考虑分母为0的情况
          
//error2:if(right==0)注意是double型
              if(right==0.0)
                    s.MakeEmpty();
//清栈,不合理的做法
                else
                    s.push(left
/right);
                    
break;
            
            
case'^':
                s.push(Power(left,right));
                
break;
            }
        }
        
}


void Calculator::Clear()
{
    s.MakeEmpty();
//直接调用容器的方法top=-1;
}


//注意:是从键盘读入后缀表达式
//1)读入的是操作符则执行DoOperator(char op)
//2) 读入的是数字则执行AddOperator(double value)
void Calculator::Run()
{
    
char ch;
    
double val;
    
while(cin>>ch&&ch!='='){
        
switch(ch){
            
case'+':
            
case'-':
            
case'*':
            
case'/':
            
case'^':
                DoOperator(ch);
                
break;
            
default:
                cin.putback(ch);
//把读取的字符重新放回输入流中
                cin>>value;
                AddOperator(value);
                
break;
        }
    }
}
posted on 2008-11-28 11:20  风荷小筑  阅读(235)  评论(0编辑  收藏  举报