【数据结构】book3_3 表达式求值

#include<iostream>
#include <stdlib.h>
using namespace std;

typedef int Status;
const int TRUE=1;
const int FALSE=0;
const int OK=1;
const int ERROR=0;
const int INFEASIBLE=-1;
const int overflow=-2;
const int STACK_INIT_SIZE=100;
const int STACKINCREMENT=10;



typedef struct{
    char *base;
    char *top;
    int stacksize;
}SqStack;

//构造一个空栈
Status InitStack(SqStack &S)
{
    S.base=(char*)malloc(sizeof(char)*STACK_INIT_SIZE); 
    if(!S.base) exit(overflow);
    S.top=S.base;
    S.stacksize=STACK_INIT_SIZE;
    return OK;
}

Status GetTop(SqStack S,char &e)
{
    if(S.top==S.base) return ERROR;
    e=*(S.top-1);
    return OK;
}

Status Push(SqStack &S,char e)
{
    if(S.top-S.base>=S.stacksize)
    {
        S.base=(char*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(char));  
        if(!S.base)exit(overflow);
        S.top=S.base+S.stacksize;
        S.stacksize+=STACKINCREMENT;
    }
    *S.top++=e;
    return OK;
}

Status Pop(SqStack &S,char &e)
{
    if(S.top==S.base) return ERROR;
    e=*--S.top;
    return OK;
}

Status StackEmpty(SqStack S){
    if(S.base==S.top)
        return TRUE;
    else
        return FALSE;
}

Status ClearStack(SqStack &S)
{
    S.top = S.base ;
    return TRUE;
}

Status DestroyStack(SqStack &S)
{
    if(S.base!=NULL)
    {
        free(S.base);
        S.stacksize=0;
        S.top=NULL;
    }
    return TRUE;
}
#include"book3_3.h"

#define ND 0  //操作数标志
#define TR 1  //操作符标志

//存放运算符的优先顺序的矩阵 op1是竖排的 op2是横排的 e表示错误 
const static char Order[7][7]=      
    {{'>','>','<','<','<','>','>'}, // +
     {'>','>','<','<','<','>','>'}, // -
     {'>','>','>','>','<','>','>'}, // *
     {'>','>','>','>','<','>','>'}, // /
     {'<','<','<','<','<','=','e'}, // (
     {'>','>','>','>','e','>','>'}, // )
     {'<','<','<','<','<','e','='}}; // #
//     +   -   *   /   (   )   #       


//比较两个操作符的优先级 op1和op2的顺序不能错
Status compOperator(char op1, char op2, char &result)
{
    int t1=9,t2=9; 
    //找到两个操作符的优先级在矩阵中的位置
    switch(op1)   
    {
    case '+': t1=0; break;
    case '-': t1=1; break;
    case '*': t1=2; break;
    case '/': t1=3; break;
    case '(': t1=4; break;
    case ')': t1=5; break;
    case '#': t1=6; break;
    default: return ERROR; break;
    }
    switch(op2)
    {
    case '+': t2=0; break;
    case '-': t2=1; break;
    case '*': t2=2; break;
    case '/': t2=3; break;
    case '(': t2=4; break;
    case ')': t2=5; break;
    case '#': t2=6; break;
    default: return ERROR; break;
    }

    result=Order[t1][t2];

    if(result=='e') 
        return ERROR;
    else 
        return OK;
}

int decideNDorTR(char t)  //判断输入的字符是操作符还是操作数
{
    if(t>=48&&t<=57)  //数字的ascii码范围
    {
        return ND;
    }
    else if(t=='+' || t=='-' || t=='*' || t=='/' || t=='(' || t==')' || t=='#')
    {
        return TR;
    }
    else
    {
        printf("error");
        return ERROR;
    }

}

char myCalculate(char op,char num1,char num2)  //字符型的运算符的计算
{
    char num;
    switch(op)
    {
    case '+': num= num1+ num2; break;
    case '-': num= num1- num2; break;
    case '*': num= num1* num2; break;
    case '/': num= num1/ num2; break;
    default: printf("error");break;
    }
    return num;
}

//计算表达式的函数 注意运算结果大小不能超过255 char型
char EvaluateExpression(char *p, int length) 
{
    SqStack OPTR, OPND;
    InitStack(OPTR);
    InitStack(OPND);
    Push(OPTR,'#');

    
    while(*p != '\0')
    {
        char t = *(p++);
        int ND_TR=decideNDorTR(t); //判断是操作符 还是 操作数

        if(ND_TR == ND) //操作数
        {
            //操作数有可能是多位的
            char num=0;
            while(t>=48&&t<=57) //字符 0-9
            {
                num = num * 10 + t - 48;
                t=*(p++);
            }
            p--; //对于 12+3 这样的情况 在取完数后 p=3  +被取走了 需要退一个 把操作符还回去
            Push(OPND,num);
        }
        else if(ND_TR == TR) //操作符
        {
            char order;
            char op1;
            char op2= t;
            GetTop(OPTR,op1);
            compOperator(op1, op2, order);
            switch(order)
            {
            case '>':   //若栈中的操作符优先级高 则取出操作数的前两个做运算 把运算后的操作符弹出  运算结果压入
                {
                    char num1,num2,num;
                    char tmp;
                    Pop(OPND,num2);
                    Pop(OPND,num1);
                    num = myCalculate(op1,num1,num2);
                    Push(OPND,num);
                    Pop(OPTR,tmp);
                    p--; //这里p要退回 让op2再进行新一轮判断 
                    break;
                }
            case '<': //若栈中操作符优先级低 新操作符进栈
                {
                    Push(OPTR,op2);
                    break;
                }
            case '=': //()或# 弹出 脱括号
                {
                    char tmp;
                    Pop(OPTR,tmp); break;
                }
            default:
                {
                    break;
                }
            }
        }


    }
    char e;
    GetTop(OPND,e);
    return e;


}

void main()
{
    char p[30]="(11+2)*3-28+123-52#";
    char ans;
    ans = EvaluateExpression(p, 30);
    printf("%d",ans);
    getchar();

}

写了好半天啊 关系总是理不清楚的感觉

posted @ 2014-03-25 14:50  匡子语  阅读(315)  评论(0编辑  收藏  举报