顺序栈实现表达式求值

来源:互联网 发布:端口类型有几种 编辑:程序博客网 时间:2024/06/06 15:43
/** Created by Microsoft Visual Studio 2013* @author: Teresa* @date: 2017-10-07* @description: 表达式求值*/#include <stdio.h>#include <stdlib.h>/*函数状态码*/#define TRUE 1  //成功#define OK 1#define FALSE 0 //失败 #define ERROR 0 //错误 #define INFEASIBLE -1   //不可行的#define OVERFLOW -2     //溢出#define STACK_INIT_SIZE 100 //存储空间初试分配量#define STACKINCREMENT 10   //存储空间分配增量typedef double OpndType;        //  操作数栈存放的数据类型typedef char OptrType;      //  操作符栈存放的数据类型typedef int Status; //函数的返回值类型 /*操作符栈*/typedef struct{    OptrType *base;   //栈底指针,始终指向栈底,如果为null说明栈不存在    OptrType *top; //栈顶指针,当top == base时,为空栈;    int stackSize; //当前已分配的存储空间,以元素为单位}OptrStack;//top-base为当前栈中的元素个数/*操作数栈*/typedef struct{    OpndType *base;    OpndType *top;    int stackSize;}OpndStack;/*操作符栈操作*///构造一个空栈Status InitOptrStack(OptrStack &S){    S.base = (OptrType *)malloc(STACK_INIT_SIZE*sizeof(OptrType));    if (!S.base)        exit(ERROR);    S.top = S.base; //栈顶指向栈底    S.stackSize = STACK_INIT_SIZE;    return OK;}//判断S是否为空栈Status OptrStackEmpty(OptrStack &S){    if (S.top == S.base)        return TRUE;    else        return FALSE;}//若栈不为空 则e返回S的栈顶元素 并返回OK 否则ERRORStatus GetOptrTop(OptrStack S, OptrType &e){    if (S.top > S.base){        e = *(S.top - 1);        return OK;    }    else        return ERROR;}//插入e为新的栈顶元素Status OptrPush(OptrStack &S, OptrType e){    if (S.top - S.base == S.stackSize){        //栈满 追加存储空间        S.base = (OptrType*)realloc(S.base, (S.stackSize + STACKINCREMENT)*sizeof(OptrType));        if (!S.base)            exit(ERROR);        S.top = S.base + S.stackSize;   //修改栈顶指针        S.stackSize += STACKINCREMENT;  //更新容量    }    *(S.top++) = e;    return OK;}//若栈不为空 则删除S的栈顶元素 用e返回其值 并返回OK 否则返回ERRORStatus OptrPop(OptrStack &S, OptrType &e){    if (S.top == S.base) return ERROR;    e = *--S.top;    return OK;}/*操作数栈操作*///构造一个空栈Status InitOpndStack(OpndStack &S){    S.base = (OpndType *)malloc(STACK_INIT_SIZE*sizeof(OpndType));    if (!S.base)        exit(ERROR);    S.top = S.base; //栈顶指向栈底    S.stackSize = STACK_INIT_SIZE;    return OK;}//判断S是否为空栈Status OpndStackEmpty(OpndStack &S){    if (S.top == S.base)        return TRUE;    else        return FALSE;}//若栈不为空 则e返回S的栈顶元素 并返回OK 否则ERRORStatus GetOpndTop(OpndStack S, OpndType &e){    if (S.top > S.base){        e = *(S.top - 1);        return OK;    }    else        return ERROR;}//插入e为新的栈顶元素Status OpndPush(OpndStack &S, OpndType e){    if (S.top - S.base == S.stackSize){        //栈满 追加存储空间        S.base = (OpndType*)realloc(S.base, (S.stackSize + STACKINCREMENT)*sizeof(OpndType));        if (!S.base)            exit(ERROR);        S.top = S.base + S.stackSize;   //修改栈顶指针        S.stackSize += STACKINCREMENT;  //更新容量    }    *(S.top++) = e;    return OK;}//若栈不为空 则删除S的栈顶元素 用e返回其值 并返回OK 否则返回ERRORStatus OpndPop(OpndStack &S, OpndType &e){    if (S.top == S.base) return ERROR;    e = *--S.top;    return OK;}//划分优先级int Rank(OptrType e){    switch (e){    case '#':        return 0; break;    case '(':        return 1; break;    case '+':    case '-':        return 2; break;    case '*':    case '/':        return 3; break;    default:        return INFEASIBLE; break;    }}//运算操作OpndType Operate(OpndType a, OpndType b, OptrType op){    OpndType c;    switch (op){    case '+':        c = a + b;        break;    case '-':        c = a - b;        break;    case '*':        c = a*b;        break;    case '/':        if (b == 0){            printf("分母为0");            return ERROR;        }        else            c = a / b;        break;    default:        printf("输入的字符不合法");        break;    }    return c;}Status StackTraverse(OpndStack S){    while (S.top > S.base){        printf("%d ", *(S.base++));    }    printf("\n");    return OK;}Status StackTraverse1(OptrStack S){    while (S.top > S.base){        printf("%c ", *(S.base++));    }    printf("\n");    return OK;}//将存储表达式的字符数组压入栈内void HandleStr(char str[]){    OptrStack optr; //定义操作符栈    OpndStack opnd; //定义操作数栈    OptrType op;    InitOptrStack(optr);    //初始化操作符栈    InitOpndStack(opnd);    //初始化操作数栈    int i, j;    OpndType f, a, b,result;    char num[100];    OptrPush(optr, '#');    for (i = 0; str[i]; i++){        switch (str[i]){        case '+':        case '-':            /*先判断当前运算符与操作符栈栈顶元素的优先级,            如果高于栈顶元素,则入栈;            小于栈顶元素,则从操作数栈中依次出两个数,            并将操作符栈中栈顶元素出栈,再将从操作数栈中出的两个数,            按从操作符栈栈中出的运算符运算,并将结果压入操作数栈中,            再将当前的操作符压入操作符栈中。*/            GetOptrTop(optr, op);            if (op == '#' || op == '('){                OptrPush(optr, str[i]);            }            else{                 OpndPop(opnd, a);                 OpndPop(opnd, b);                 OptrPop(optr, op);                 OpndPush(opnd, Operate(b, a, op));                 OptrPush(optr, str[i]);            }            break;        case '*':        case '/':            GetOptrTop(optr, op);            if (Rank(str[i]) > Rank(op) || op == '('){                OptrPush(optr, str[i]);            }            else{                OpndPop(opnd, a);                OpndPop(opnd, b);                OptrPop(optr, op);                OpndPush(opnd, Operate(b, a, op));                OptrPush(optr, str[i]);            }            break;        case '(':            OptrPush(optr,str[i]);            break;        case ')':            GetOptrTop(optr, op);            while (op != '('){                OpndPop(opnd, a);                OpndPop(opnd, b);                OptrPop(optr, op);                OpndPush(opnd, Operate(b, a, op));                GetOptrTop(optr, op);            }            OptrPop(optr, op);            break;        default:            j = 0;            do{                num[j] = str[i];                i++;                j++;            } while (str[i] > '0' && str[i] < '9' || str[i] == '.');            num[j] = '\0';            i--;            f = atof(num);            OpndPush(opnd, f);            break;        }    }    GetOptrTop(optr, op);    while (op != '#'){        OpndPop(opnd, a);        OpndPop(opnd, b);        OptrPop(optr, op);        OpndPush(opnd, Operate(b, a, op));        GetOptrTop(optr, op);    }    GetOpndTop(opnd, result);    printf("表达式%s=%g\n", str, result);}int main(){    char str[100];    printf("请输入表达式:\n");    scanf("%s", str);    HandleStr(str);    return 0;}