中缀表达式求值
例如:2*(3+5)-7
定义两个栈,一个操作数栈,一个运算符栈,首先需要定义运算符的优先级,如图。
将表达式的前后都加上‘#’方便操作。#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;
}