【数据结构】 栈的应用-表达式求值

 表达式求值:

表达式求值是程序设计语言编译中的一个基本问题,任何一个表达式都有操作数、运算法则和界限符组成。其中操作数可以是常量、变量或常量标识符。运算符可以分为算术运算符、关系运算符和逻辑运算符。

对于表达式的记法主要有三种:前缀表达式(波兰式)、中缀表达式和后缀表达式(逆波兰式),它们之间的区别在于运算符相对于操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前,中缀表达式的运算符位于与其相关的操作数中间,而后缀表达式的运算符位于与其相关的操作数之后。例如给定表达式:    ( a + b ) * ( c - d / e ) - f ;

前缀表达式: -  *  +  a  b  - c  /  d  e  f

中缀表达式: a  +  b  *  c  -  d  /  e  -  f

后缀表达式:a  b  +  c  d  e  /  -  *  f  -


#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.h>
#include<windows.h>
#include<iostream>
#define SElemType int
#define inf 0x3f3f3f3f
using namespace std;
typedef struct LNode{
    SElemType data;
    struct LNode *next;
    LNode (SElemType Data=0,struct LNode * Next=NULL){
        data=Data;
        next=Next;
    }
}LNode ,*LinkList ;
void InitStack(LinkList &LS){
    LS=NULL;
}
bool StackEmpty(LinkList LS){
    return LS?false:true;
}
int StackLength(LinkList Ls){
    int cnt=0;
    LinkList p=Ls;
    while(p){
        cnt++;p=p->next;
    }
    return cnt;
}
void Push(LinkList &LS,SElemType e){
    LinkList s;
    s=new LNode(e,LS);
    LS=s;
}
void Pop(LinkList &LS,SElemType &e){
    if(LS==NULL){
        printf("error !!! Stack is empty !\n");
        return ;
    }
    e=LS->data;
    LinkList s=LS;
    LS=LS->next;
    delete s;
}
void GetTop(LinkList LS,SElemType &e){
    if(!LS){
        printf("error !!! Stack is empty !\n");
        return ;
    }
    e=LS->data;
}
char Prior[10][10]={
    ">><<<>>",
    ">><<<>>",
    ">>>><>>",
    ">>>><>>",
    "<<<<<= ",
    ">>>> >>",
    "<<<<< ="
};
int Operator(int a,char theta,int b){
    if(theta=='/'&&!b){
        return inf*printf("  error!!! \"/0\" ");
    }
    switch(theta){
        case '+':   return a+b; break;
        case '-':   return a-b; break;
        case '*':   return a*b; break;
        case '/':   return a/b; break;
    }
}
char Oper[]="+-*/()#";
int Locate(char theta){
    for(int i=0;i<7;i++)
        if(theta==Oper[i])
            return i;
    return -1*printf("error !!! theta is wrong \n");
}
char Compare(char theta1 , char theta2){
    int i=Locate(theta1);
    int j=Locate(theta2);
    if(~i&&~j)
        return Prior[i][j];
}
void EvaluateExpression(char str[]){
    LinkList Optr,Opnd;
    printf("%s = ",str);
    char *p=str;
    int len=strlen(str);
    str[len]='#';
    str[len+1]='\0';
    int ch,theta;
    int a,b;
    InitStack(Optr);
        Push(Optr,'#');
    InitStack(Opnd);
    while(*p=='\0'||*p!='#'||ch!='#'){
        if(*p==' '){
            p++;
        }else if(*p>='0'&&*p<='9'){
            int num=0;
            while(*p!='#'&&*p>='0'&&*p<='9'){
                num=num*10+(*p-'0');
                p++;
            }
            //printf("Num = %d\n",num);
            Push(Opnd,num);
        }
        else{
            GetTop(Optr,ch);
            //printf("%c\n",ch);
            switch(Compare(ch,*p)){
                case '<':   Push(Optr,*p);p++;    break;
                case '=':   Pop(Optr,ch); p++;    break;
                case '>':   Pop(Opnd,b),Pop(Opnd,a);Pop(Optr,theta);
                //printf("%d %c %d = %d\n",a,theta,b,Operator(a,theta,b));
                            Push(Opnd,Operator(a,theta,b));
                            break;
            }
        }
        GetTop(Optr,ch);
    }
    GetTop(Opnd,a);
    //return a;
    printf("%d\n",a);
}
void EvaluatePreExpression(char str[]){
    int n=strlen(str),a,b;
    char *p=str+n-1;
    LinkList Opnd;
    InitStack(Opnd);
    while(n>0){
        if(*p==' '){
            p--;n--;
        }else if('0'<=*p&&*p<='9'){
            LinkList S;
            InitStack(S);
            while(*p!=' '&&'0'<=*p&&*p<='9'){
                Push(S,*p-'0');
                p--;n--;
            }
            int num=0,ch,e;
            while(!StackEmpty(S)){
                Pop(S,e);
                num=num*10+e;
            }
            Push(Opnd,num);
        }else{
        /*
            if(Locate(*p)>=0){
                printf("p  =  '%c'\n",*p);
            }
        */
            Pop(Opnd,a); Pop(Opnd,b);
            Push(Opnd,Operator(a,*p,b));
            p--;n--;
        }
    }
    GetTop(Opnd,a);
    printf("%s = %d\n",str,a);
    //return a;
}
void EvaluatePostExpression(char *str){
    char *p = str;
    LinkList Opnd;
    InitStack(Opnd);
    int a,b;
    while(*p!='\0'){
        if(*p==' '){
            p++;
        }else if('0'<=*p&&*p<='9'){
            int num=0;
            while('0'<=*p&&*p<='9'){
                num=num*10+*p-'0';
                p++;
            }
            Push(Opnd,num);
        }else{
            Pop(Opnd,b);Pop(Opnd,a);
            Push(Opnd,Operator(a,*p,b));
            p++;
        }
    }
    GetTop(Opnd,a);
    //return a;
    printf("%s = %d\n",str,a);
}
void get_s(char *s){
    char ch=getchar();
    int cnt=0;
    while(ch!='\n'){
        s[cnt++]=ch;
        ch=getchar();
    }
    s[cnt]='\0';
}
void Warning(int n=5){
    if(n==-1){
        puts("\t\t********************************");
        puts("\t\t**                            **");
        puts("\t\t**请选择一种表达式来进行计算:**");
        puts("\t\t**                            **");
        puts("\t\t** 1、前缀表达式:             **");
        puts("\t\t** 2、中缀表达式:             **");
        puts("\t\t** 3、后缀表达式:             **");
        puts("\t\t** 0、退出                    **");
        puts("\t\t**                            **");
        puts("\t\t********************************");
        puts("");
        printf("\t\t请选择其中一项:");

    }else if (n==-2){
        printf("\t\t");
    }else if(n==0){
        puts("\t\t退出程序");
    }else if(n==1){
        puts("\t\t请输入前缀表达式:");
        printf("\t\t");
    }else if(n==2){
        puts("\t\t请输入中缀表达式:");
        printf("\t\t");
    }else if (n==3){
        puts("\t\t请输入后缀表达式:");
        printf("\t\t");
    }else {
        puts("\t\t输入错误,请重新输入!!!");
    }

}
int main()
{
    int ans,No;
    while(1){
        No=-3;
        char s[100]="\0",t[100];
        Warning(-1);
        scanf("%s",t);
        getchar();
        if(strlen(t)==1){
            No=t[0]-'0';
        }
        Warning(No);
        switch(No){
            case 0: return 0;
            case 1: get_s(s);Warning(-2);EvaluatePreExpression(s); break;
            case 2: get_s(s);Warning(-2);EvaluateExpression(s);    break;
            case 3: get_s(s);Warning(-2);EvaluatePostExpression(s);break;
        }
        Sleep(2000);
        system("cls");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Z_sea/article/details/85162295