#include<iostream>
#include<stdlib.h>
using namespace std;
struct OPTR //运算符栈
{
char *base;
char *top;
int stacksize;
};
struct OPND //运算数栈
{
int *base;
int *top;
int stacksize;
};
//heavy load
void initstack(OPTR &S) //initialize OPTR [it can't more allot ]
{
S.base=(char *)malloc(sizeof(char)*20); //若一开始为 *S 指针的 s->base 相当于 *s.base
if(!S.base) exit(0);
S.top=S.base;
S.stacksize=20;
}
void initstack(OPND &N) //initialize OPND [it can't more allot ]
{
N.base=(int *)malloc(sizeof(int)*20);
if(!N.base) exit(0);
N.top=N.base;
N.stacksize=20;
}
char gettop(OPTR &S,char &E) //gain the top element of char
{
if(S.base==S.top) exit(9);
E=*(S.top-1);
return E;
}
int gettop(OPND &N,int &E) //gain the top element of int
{
//doesn't consider empty stack
E=*(N.top-1);
return E;
}
void push(OPTR &S,char &E) //push character
{
if(S.top-S.base==S.stacksize)
{
S.base=(char *)realloc(S.base,(20+10)*sizeof(char));
S.top=S.base+S.stacksize;
S.stacksize+=10;
}
*S.top++=E;
}
void push(OPND &N,char &E) // push number
{
//doesn't consider stack full
int I;
I=int(E)-48;
*N.top++=I;
}
int push(OPND &N,int E) // push number while E is int
{
//doesn't consider stack full
*N.top++=E;
}
void pop(OPTR &S,char &E) //pop the top character
{
if(S.base==S.top) exit(0);
E=*--S.top;
}
void pop(OPND &N,int &E) //pop the top number
{
//doesn't consider empty stack
E=*--N.top;
}
void initexp(char a[]) //initialize expression
{
int i;
for(i=0;i<30;i++) //[in the beginning ,the i's max number is 99 over the 30 ,so that i can't use malloc as usual]
//对数组a以外的空间进行赋值,导致溢站栈出错
{
a[i]='\0';
}
}
char precede(char topc,char nowc)
{
int tc,nc;
switch (topc)
{
case '#':tc=1;break;
case '(':tc=2;break;
case '+':tc=3;break;
case '-':tc=3;break;
case '*':tc=4;break;
case '/':tc=4;break;
case ')':tc=5;break;
}
switch (nowc)
{
case '#':nc=1;break;
case '(':nc=2;break;
case '+':nc=3;break;
case '-':nc=3;break;
case '*':nc=4;break;
case '/':nc=4;break;
case ')':nc=5;break;
}
if(topc==')'&&nowc=='('||topc=='#'&&nowc==')'||topc=='('&&nowc=='#')
return 'x';
else if(topc=='('&&nowc==')'||topc=='#'&&nowc=='#')
return '=';
else if(nc==2)
return '<';
else if(nc==5)
return '>';
else if(tc<nc)
return '<';
else if(tc>=nc)
return '>';
}
int calculate(int a,char theta,int b)
{
switch(theta)
{
case '+':return a+b;break;
case '-':return a-b;break;
case '*':return a*b;break;
case '/':if(a==0) {cout<<"division error "<<endl; exit(0);} else{return a/b;} break; //use for exact division
}
}
void evaluaterexpression(char a[],OPTR &S,OPND &N)
{
int i=0;
char theta;
int c,b;
push(S,a[i]);
i++;
while (S.base!=S.top||a[i-1]!='#') //a[i]!='\0'无法使用
{
if(47<a[i]&&a[i]<58) push(N,a[i]); //error in 47<a[i]<58
else
{
switch(precede(gettop(S,theta),a[i]))
{
case 'x':cout<<"the expression error"<<endl;exit(0);break;
case '<':push(S,a[i]);break;
case '=':pop(S,theta);break;
case '>':pop(S,theta);
pop(N,b); //b,c位置错位影响除法
pop(N,c);
push(N,calculate(c,theta,b));
i--; //若无则会跳过 当前这个还未适用的符号
break;
}
}
i++;
//cout<<endl<<gettop(N,c); show the OPND's changes
}
if(a[i]!='\0'&&S.base!=S.top)
cout<<"calculate error "<<endl;
else cout<<" = "<<gettop(N,c);
}
int main ()
{
char a[30]; // [only calculate the number less than ten]
initexp(a);
cout<<"please input expression"<<endl;
cin>>a;
cout<<"the expression is :"<<endl;
cout<<a;
OPTR S; //无需指针,若用指针要间访很麻烦
OPND N;
//use malloc to test find where the problem arises
initstack(S);
initstack(N);
// test cout<<precede('(',')')<<precede('+','+')<<precede('(','+')<<precede('+','(');
//test cout<<calculate(1,'+',2)<<endl;cout<<calculate(0,'/',3); 能证明一个cout一个流
evaluaterexpression(a,S,N);
return 0;
}