#include <iostream>
#include <math.h>
#include <stack>
using namespace std;
const int size = 30;
class Calculator;
template <class T>
class Stack
{
public:
virtual bool IsEmpty()const=0;
virtual bool IsFull()const=0;
virtual bool Top(T &x)const=0;
virtual bool Push(T x)=0;
virtual bool Pop()=0;
virtual void Clear()=0;
};
template <class T>
class SeqStack:public Stack<T>
{
public:
SeqStack(int mSize);
~SeqStack(){delete []s;}
bool IsEmpty()const {return top==-1;}
bool IsFull()const {return top==maxTop;}
bool Top( T &x)const;
bool Push(T x);
bool Pop();
void Clear(){top=-1;}
friend Calculator;
private:
int top;
int maxTop;
T *s;
};
template <class T>
SeqStack<T>::SeqStack(int mSize)
{
maxTop=mSize-1;
s=new T[mSize];
top=-1;
}
template <class T>
bool SeqStack<T>::Top(T &x)const
{
if(IsEmpty())
{ cout<<"Empty"<<endl;return false; }
x=s[top];
return true;
}
template <class T>
bool SeqStack<T>::Push(T x)
{
if(IsFull())
{
cout<<"Overflow"<<endl;
return false;
}
s[++top]=x;
return true;
}
template <class T>
bool SeqStack<T>::Pop() {
if(IsEmpty())
{
cout<<"underflow"<<endl;return false;
}
top--;
return true;
}
class Calculator
{
private:
SeqStack<double> s;
void PushOperand(double);
bool GetOperand(double &,double &);
void DoOperator(char);
public:
Calculator(int maxSize):s(maxSize) {};
void Run();
void Clear() {s.Clear();}
};
void Calculator::PushOperand(double op)
{
s.Push(op);
}
bool Calculator::GetOperand(double &op1,double &op2)
{
if(!s.Top(op1)) {
cout<<"Missing operand"<<endl;
return false;
}
s.Pop();
if(!s.Top(op2)) {
cout<<"Missing operand"<<endl;
return false;
}
s.Pop();
return true;
}
void Calculator::DoOperator(char oper)
{
bool result;
double oper1,oper2;
result=GetOperand(oper1,oper2);
if(result)
switch(oper)
{
case '+':s.Push(oper2+oper1); break;
case '-':s.Push(oper2-oper1); break;
case '*':s.Push(oper2*oper1); break;
case '/':if(fabs(oper1)<1e-6) {
cout<<"Divide by 0"<<endl;
}
else s.Push(oper2/oper1); break;
case '^':s.Push(pow(oper2,oper1)); break;
}
else Clear();
}
int icp(char ch)
{
switch(ch)
{
case '#': return 0;
case '(': return 7;
case '*':
case '/': return 4;
case '+':
case '-': return 2;
case ')': return 1;
default: cout<<"Error Input!"<<endl;
}
return 0;
}
int isp(char ch)
{
switch(ch)
{
case '#': return 0;
case '(': return 1;
case '*':
case '/': return 5;
case '+':
case '-': return 3;
case ')': return 7;
default: cout<<"Error Input!"<<endl;
}
return 0;
}
char *InfixToPostfix()
{
SeqStack <char> s(size);
char ch,y;
s.Push('#');
int i = 0;
char *Postfix = new char[size*sizeof(char)];
for(int j=0;j<size;j++)
{
Postfix[j]='\0';
}
while(cin>>ch,ch!='#') {
if(isdigit(ch)||isalpha(ch)) Postfix[i++] = ch;
else if(ch==')') {
for(s.Top(y),s.Pop();y!='(';s.Top(y),s.Pop()) Postfix[i++]=y;
}
else {
for(s.Top(y),s.Pop();icp(ch)<=isp(y);s.Top(y),s.Pop())
{
Postfix[i++]=y;
}
s.Push(y);
s.Push(ch);
}
}
while(!s.IsEmpty()) {
s.Top(y);
s.Pop();
if(y!='#') Postfix[i++]=y;
}
Postfix[i]='#';
cout<<Postfix<<endl;
return Postfix;
}
void Calculator::Run()
{
char c;
double newop;
char *postfix = InfixToPostfix();
int i=0;
c=postfix[i];
while(c!='#') {
switch(c) {
case '+':
case '-':
case '*':
case '/':
case '^':DoOperator(c); break;
default:cin.putback(c);
cin>>newop;
PushOperand(newop);
break;
}
c = postfix[++i];
}
if(s.Top(newop))
cout<<newop<<endl;
}
int main()
{
Calculator Cal(size);
Cal.Run();
return 0;
}
栈结构演示程序
最新推荐文章于 2024-09-11 22:20:04 发布