表达式求值——栈实现

来源:互联网 发布:网络教育统考报考失败 编辑:程序博客网 时间:2024/06/05 20:10

要点总结

  • 分成两个栈,一个操作数栈,一个运算符栈
  • judge(c):判断读入的字符是操作数还是运算符,便于压栈
  • precede(a,b):判断读入的运算符和运算符栈的栈顶元素的优先级大小;如果大于栈顶元素的优先级,则将它压栈;否则,就把栈顶元素弹出来,再把操作数栈中的两个操作数弹出来,与该运算符做相应的运算。
  • Operate():上文提到的,进行相应的运算的函数实现
#include <iostream>#include <stdlib.h> using namespace std;typedef int SElemType;              // 栈的元素类型#define STACK_INIT_SIZE 10          // 存储空间初始分配量#define STACKINCREMENT 2            // 存储空间分配增量/* *顺序栈的结构体 * */typedef struct SqStack{    SElemType *base;                // 在栈构造之前和销毁之后,base的值为NULL    SElemType *top;                 // 栈顶指针    int stacksize;                  // 当前已分配的存储空间,以元素为单位}SqStack;/* *构造一个栈 * */int InitStack(SqStack *S){    // 为栈底分配一个指定大小的存储空间    (*S).base = (SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));    if( !(*S).base )        exit(0);        // 存储分配失败    (*S).top = (*S).base;   // 栈底与栈顶相同表示一个空栈    (*S).stacksize = STACK_INIT_SIZE;    return 1;}/* *获取栈顶元素 * */int GetTop(SqStack S,SElemType *e){    if(S.top > S.base)    {        *e = *(S.top-1);    // 栈顶指针的下一个位置为栈顶元素        return 1;    }    else        return 0;}/* *入栈(压栈) * */int Push(SqStack *S, SElemType e){    if((*S).top - (*S).base >= (*S).stacksize)   // 栈满,追加存储空间    {        (*S).base = (SElemType *)realloc((*S).base,            ((*S).stacksize + STACKINCREMENT) * sizeof(SElemType));        if( !(*S).base )            exit(0); // 存储分配失败        (*S).top = (*S).base+(*S).stacksize;        (*S).stacksize += STACKINCREMENT;    }    *((*S).top)++=e;    // 这个等式的++ * 优先级相同,但是它们的运算方式,是自右向左    return 1;}/* *出栈 * */int Pop(SqStack *S,SElemType *e){    if((*S).top == (*S).base)        return 0;    *e = *--(*S).top;    // 这个等式的++ * 优先级相同,但是它们的运算方式,是自右向左    return 1;}bool judge(SElemType c){    switch(c)    {    case '+':    case '-':    case '*':    case '/':    case '(':    case ')':    case '#':return true;    default:return false;    }}SElemType precede(SElemType a ,SElemType b){    SElemType f;    switch(b)    {    case '+':    case '-':        {            if(a == '(' ||a == '#')            {                f='<';            }            else            {                f='>';            }            break;        }    case '*':    case '/':        {            if(a=='*'||a=='/'||a==')')            {                f='>';            }            else            {                f='<';            }            break;        }    case '(':        {            if(a==')')            {                cout<<"error!"<<endl;                return 0;            }            else{                f='<';            }            break;        }    case ')':        {            if(a=='('||a=='#')            {                if(a=='(')                {                    f='=';                }                else                {                    cout<<"error!"<<endl;                    return 0;                }            }            else            {                f='>';            }            break;        }    case '#':        {            if(a=='('||a=='#')            {                if(a=='#')                {                    f='=';                }                else                {                    cout<<"error!"<<endl;                    return 0;                }            }            else            {                f='>';            }            break;        }    }    return f;}SElemType Operate(SElemType t1,SElemType theta,SElemType t2){    SElemType a,b;    a=t1-48;    b=t2-48;    switch(theta)    {    case '+':        return a+b+48;    case '-':        return a-b+48;    case '*':        return a*b+48;    case '/':        return a/b+48;    }}SElemType EvaluateExpression(){    SElemType a,b,c,x,theta;    SqStack OPTR,OPND;    InitStack(&OPTR);    InitStack(&OPND);    Push(&OPTR,'#');    c=getchar();    while(c!= '#' || x != '#')    {        if(!judge(c))//不是运算符就进栈        {            Push(&OPND,c);            c=getchar();        }        else        {            GetTop(OPTR,&x);            switch( precede(x,c) )            {            case '<': //栈顶元素优先级低                {                    Push(&OPTR,c);                    c=getchar();                    break;                }            case '=':                {                    Pop(&OPTR,&x);                    c=getchar();                    break;                }            case '>':                {                    Pop(&OPTR,&theta);                    Pop(&OPND,&b);                    Pop(&OPND,&a);                    Push(&OPND,Operate(a,theta,b));                    break;                }            }        }        GetTop(OPTR,&x);    }    GetTop(OPND,&x);    return x;}int main(){    printf("请输入算术表达式,并以#结束\n");    printf("例如:3*(7-5)#\n");    printf("%c\n",EvaluateExpression());    return 0;}
原创粉丝点击