不错的思路,不错的设计(代码摘自殷人困数据结构书)
#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;
}
}
}
#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;
}
}
}