数据结构——栈实现表达式的运算(+ - * /)

#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;
}
 

猜你喜欢

转载自blog.csdn.net/hrainning/article/details/86367867
今日推荐