【数据结构】中缀表达式表达式求值

一、问题描述

中缀表达式求值
例如:2*(3+5)-7

二、解题思路

定义两个栈,一个操作数栈,一个运算符栈,首先需要定义运算符的优先级,如图。
【数据结构】中缀表达式表达式求值_第1张图片

将表达式的前后都加上‘#’方便操作。#2*(3+5)-7#
首先从前往后扫描字符串,当遇到操作数时,就将其压入操作数栈。当遇到运算符时,首先和运算符栈的栈顶元素比较,当小于,压栈(运算符),大于,出栈(运算符)并且从运算符栈出两个字符,先出做后件,后出做前件,运算完后将其压入操作数栈,注意并不继续扫描下一个字符,当等于时,若为括号弹出括号但不从操作数栈弹出两个操作数。当且仅当扫描的字符为‘#’并且栈顶元素为‘#’时,停止扫描。此时操作数栈的栈顶元素即是表达式的结果。

#include 
#include 
using namespace std;

int OPND[100];
char OPTR[100]; //操作数栈、操作符栈
int topN=-1,topT=-1;

//栈的基本操作
//压栈,弹栈,取栈顶元素
void push(char *OPTR,char ch){
     
        OPTR[++topT]=ch;
}
void push(int *OPND,int val){
     
        OPND[++topN]=val;
}
char pop(char *OPTR){
     
        return OPTR[topT--];
}
int pop(int *OPND){
     
        return OPND[topN--];
}
int getTop(int *OPND){
     
    return OPND[topN];
}
char getTop(char *OPTR){
     
    return OPTR[topT];
}

//定义一个二维字符数组存放优先级表
char arr[7][7]= {
     '>','>','<','<','<','>','>',
                 '>','>','<','<','<','>','>',
                 '>','>','>','>','<','>','>',
                 '>','>','>','>','<','>','>',
                 '<','<','<','<','<','=','\0',
                 '>','>','>','>','\0','>','>',
                 '<','<','<','<','<','\0','='
                };
//定义数组下标的字符
int opCH(char ch){
     
    int i;
        switch(ch){
     
    case '+':{
     
        i=0;
        break;
    }
    case '-':{
     
        i=1;
        break;
    }
    case '*':{
     
        i=2;
        break;
    }
    case '/':{
     
        i=3;
        break;
    }
    case '(':{
     
        i=4;
        break;
    }
    case ')':{
     
        i=5;
        break;
    }
    case '#':{
     
        i=6;
        break;
    }
 }
 return i;
}
//比较运算符的优先级
char percede(char ch1,char ch2){
     
    int i,j;
    i=opCH(ch1);
    j=opCH(ch2);
    return arr[i][j];
}
//运算
int operate(int a,char theta,int b){
     
    switch(theta){
     
    case '+':{
     
            return a+b;
    }
    case '-':{
     
            return a-b;
    }
    case '*':{
     
            return a*b;
    }
    case '/':{
     
            return a/b;
    }
 }
 return 0;
}

int main(){
     
    string s;//表达式
    char theta;//运算符
    int a,b,c;
    push(OPTR,'#');//先将操作符栈压入一个‘#’
    cout<<"请输入中缀表达式,以#符号结束"<<endl;
    cin>>s;
    for(int i=0;s[i]!='#'||getTop(OPTR)!='#';i++){
     
    //比较ASCII码 49-57为数字1-9
        if(s[i]>48&&s[i]<58){
     
            c=s[i]-48; //转换成整型数
            //压入操作数栈
            push(OPND,c);
        }else if(s[i]=='*'||s[i]=='/'||s[i]=='+'||s[i]=='-'||
                 s[i]=='('||s[i]==')'||s[i]=='#'){
     
                 //比较扫描到的字符和栈顶元素的优先级
            switch(percede(getTop(OPTR),s[i])){
     
        case '>':{
     
        		//栈顶元素优先级高,操作符栈弹出一个操作符,操作数栈弹出两个操作数,先弹做后件,后弹做前件
                theta=pop(OPTR);
                b=pop(OPND);
                a=pop(OPND);
                //将运算结果压入操作数栈
                push(OPND,operate(a,theta,b));
                //注意一定要将i--因为大于不扫描下一个字符
                i--;
                break;
        }
        case '<':{
     
        //栈顶元素优先级低,压入操作符栈
                push(OPTR,s[i]);
                break;
        }
        case '=':{
     
        //当为括号时,从操作符栈弹出,但不从操作数栈弹出两个数
                if(s[i]==')'){
     
                    pop(OPTR);
                }
        }
        }
    }
 }
 cout<<getTop(OPND)<<endl;
    return 0;
}

三、结果展示

【数据结构】中缀表达式表达式求值_第2张图片
【数据结构】中缀表达式表达式求值_第3张图片
【数据结构】中缀表达式表达式求值_第4张图片

四、局限

  • 只能运算个位数,不能运算大于个位数的数
  • 必须保证表达式格式正确

你可能感兴趣的:(算法,数据结构,数据结构,算法,栈)