中缀表达式求值,算法思路的原理图示
(代码写的不简洁,但运行结果没问题,思路比较好看出来,仅仅为不会的小白参考和自己记录下来)
注意点
1.遇到操作符出栈时,需要弹出两个操作数,先弹出的操作数y为减数或除数,后弹出的x为被减数或被除数。
2.输入中缀表达式是字符串,字符串中的数字需要转化成整形数据,下面代码的getNum()函数实现。
3.操作符栈和操作数栈存放两种不同类型的变量。
#include<stdio.h>
#include<stdlib.h>
#define MAXN 100
#define STACKSIZE 100
#define NULL 0
#define OK 1
#define ERROR 0
typedef char ElemType;
typedef struct {
ElemType date[STACKSIZE];
int top;
}SqStack2; //存放操作符
typedef struct {
int date[STACKSIZE];
int top;
}SqStack1; //存放操作数
SqStack2 * InitSqStack2(){
SqStack2 * S;
S=(SqStack2 *)malloc(sizeof(SqStack2));
if(!S) return NULL;
else {
S->top=-1;
return S;
} //初始化操作符栈
}
SqStack1 * InitSqStack1(){
SqStack1 * S;
S=(SqStack1 *)malloc(sizeof(SqStack1));
if(!S) return NULL;
else {
S->top=-1;
return S;
}
} //初始化操作数栈
int Push2(SqStack2 *S,ElemType x){
if(S->top==STACKSIZE-1){
printf("空间已满222,无法压栈");
return ERROR;}
else{
S->date[++S->top]=x;
return OK;
}
} //操作符压栈
int Push1(SqStack1 *S,int x){
if(S->top==STACKSIZE-1){
printf("空间已满111,无法压栈111");
return ERROR;}
else{
S->date[++S->top]=x;
return OK;
}
} //操作数压栈
int Pop2(SqStack2 *S,ElemType *x){
if(S->top==-1){
printf("空间为空,无法出栈");
return ERROR; }
else{
*x=S->date[S->top--];
return OK;
}
} //操作符出栈
ElemType GetTop(SqStack2 *S){
return (S->date[S->top]);
} //操作符取栈顶元素
int GetTop1(SqStack1 *S){
return (S->date[S->top]);
} //操作数取限定元素
int IsEmpty(SqStack2 * S){
return (S->top==-1);
} //判断操作符栈是否为空
int ISFUll(SqStack2 * S){
return (S->top==STACKSIZE-1);
}
int Pop1(SqStack1 *S,int *x){
if(S->top==-1){
printf("空间为空,无法出栈111");
return ERROR; }
else{
*x=S->date[S->top--];
return OK;
}
} //操作实栈出栈
int getNum(char * expStr,int *len){
int j=0,val=0;
while(expStr[j]>='0'&&expStr[j]<='9'){
val=val*10+(expStr[j]-'0');
j++;}
*len=j;
return val;
} //将中缀表达式的字符转化成整形
void main(){
char* Str = (char*)malloc(MAXN*sizeof(char));
printf("请输入中缀表达式");
gets(Str);
SqStack1 * S1 = InitSqStack1();
SqStack2 * S2 = InitSqStack2();
int x,y,i=0,j=0;
char z=NULL;
while(Str[i]!='#'){
if(Str[i]>='0'&&Str[i]<='9'){
x=getNum(Str+i,&j);
Push1(S1,x);
i=i+j;
}
else if(Str[i]=='('){
Push2(S2,Str[i]);
i++;
}
else if(Str[i]=='*'||Str[i]=='/'){
if(GetTop(S2)=='+'||GetTop(S2)=='-'||GetTop(S2)=='('||IsEmpty(S2)){
Push2(S2,Str[i]);
}else{Pop2(S2,&z);
Pop1(S1,&y);
Pop1(S1,&x);
if(z=='*') Push1(S1,x*y);
if(z=='/') Push1(S1,x/y);
while(GetTop(S2)!='+'&&GetTop(S2)!='-'&&GetTop(S2)!='('&&!IsEmpty(S2)){
Pop2(S2,&z);
Pop1(S1,&y);
Pop1(S1,&x);
if(z=='*') Push1(S1,x*y);
if(z=='/') Push1(S1,x/y);
}
Push2(S2,Str[i]);
}i++;
}
else if(Str[i]=='+'||Str[i]=='-')
{
if(GetTop(S2)=='('||IsEmpty(S2)) Push2(S2,Str[i]);
else {
{Pop2(S2,&z);
Pop1(S1,&y);
Pop1(S1,&x);
if(z=='+') Push1(S1,x+y);
if(z=='-') Push1(S1,x-y);
if(z=='*') Push1(S1,x*y);
if(z=='/') Push1(S1,x/y);
}
while(GetTop(S2)!='('&&!IsEmpty(S2))
{Pop2(S2,&z);
Pop1(S1,&y);
Pop1(S1,&x);
if(z=='+') Push1(S1,x+y);
if(z=='-') Push1(S1,x-y);
if(z=='*') Push1(S1,x*y);
if(z=='/') Push1(S1,x/y);
}
Push2(S2,Str[i]);
}
i++;
}
else if(Str[i]==')'){
Pop2(S2,&z);
while(z!='('){
Pop1(S1,&y);
Pop1(S1,&x);
if(z=='+') Push1(S1,x+y);
else if(z=='-') Push1(S1,x-y);
else if(z=='*') Push1(S1,x*y);
else if(z=='/') Push1(S1,x/y);
Pop2(S2,&z);
}
i++;
}
}
while(!IsEmpty(S2)){
Pop2(S2,&z);
Pop1(S1,&y);
Pop1(S1,&x);
if(z=='+') Push1(S1,x+y);
else if(z=='-') Push1(S1,x-y);
else if(z=='*') Push1(S1,x*y);
else if(z=='/') Push1(S1,x/y);
}
printf("结果为:%d",S1[0]);
system("PAUSE");
}