#include <stdio.h> #include <stdlib.h> #define MAXSIZE 100 #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE 0 typedef int Status; typedef struct{ char data[MAXSIZE]; int top; //栈顶位置 }Stack; //这个栈用来进行中缀转后缀过程中暂存运算符 typedef struct{ float data[MAXSIZE]; int top; }ValueStack; //这个栈用来在后缀表达式求值时存放操作数 //1.栈的初始化 Status InitStack(Stack *s, int n){ if(n>MAXSIZE || n<1){ printf("输入的长度有误!\n"); return ERROR; } int i; for(i=0;i<n;i++){ s->data[i] = 'a'; } s->top = 0; return OK; } Status InitValueStack(ValueStack *v,int n){ if(n>MAXSIZE || n<1){ printf("输入的长度有误!\n"); return ERROR; } int i; for(i=0;i<n;i++){ v->data[i] = 0.0; } v->top = 0; return OK; } //2.入栈操作 Status Push(Stack *s,char c){ //先判断栈是否已满 if(MAXSIZE-1 == s->top){ printf("栈已满\n"); return ERROR; } //入栈之前需要先将栈顶指针移动到下一个可用的位置 ++(s->top); //将待入栈元素存到栈顶 s->data[s->top] = c; return OK; } Status PushValue(ValueStack *v,float f){ //先判断栈是否已满 if(MAXSIZE-1 == v->top){ printf("栈已满\n"); return ERROR; } //入栈之前需要先将栈顶指针移动到下一个可用的位置 ++(v->top); //将待入栈元素存到栈顶 v->data[v->top] = f; return OK; } //3.出栈操作 Status Pop(Stack *s, char *c){ //首先判断栈是否已空 if(0 == s->top){ printf("栈为空\n"); return ERROR; } *c = s->data[s->top]; --(s->top); return OK; } //4.判断栈是否为空 Status IsStackEmpty(Stack *s){ if(0 == s->top) return TRUE; else return FALSE; } //5.获取栈顶元素 Status GetTop(Stack *s, char *c){ if(0 == s->top){ printf("栈为空,无法获取元素\n"); return ERROR; } *c = s->data[s->top]; return OK; } //6.判断运算符的优先级 Status Priority(char op1,char op2){// if(Priority(c,exp[i])){ //op1为栈顶的运算符 if(op1 == '+' || op1 == '-'){ if(op2 == '+' || op2 == '-') return TRUE; else return FALSE; } if(op1 == '*' || op1 == '/') return TRUE; } //7.判断是否是运算符 Status IsOp(char c){ if(c == '+' || c == '-' || c == '*' || c == '/') return TRUE; else return FALSE; } //8.判断是否是数字 Status IsNum(char c){ if(c >= '0' && c <= '9') return TRUE; else return FALSE; } //9.中缀表达式转后缀表达式 void MidToFinal(char *exp, char *finalExp){ int i,j; Stack s; char c; //用来存放栈顶元素或出栈元素 i = j = 0; InitStack(&s,MAXSIZE); //初始化栈 while(exp[i] != '\0'){ //如果获取的是数值,则将其存放到后缀表达式数组中 if(IsNum(exp[i])){ finalExp[j] = exp[i]; printf("后缀表达式数组中的内容为:%c,j=%d\n",finalExp[j],j); j++; }else{ if(IsOp(exp[i])){ //判断读到的是否是合法的运算符 //如果是合法的运算符,则需要依次对栈中的运算符进行优先级比较 while(!IsStackEmpty(&s)){ GetTop(&s,&c); if(Priority(c,exp[i])){ //如果栈中的优先级高,则需要将栈顶元素出栈到后缀表达式数组中 Pop(&s,&c); finalExp[j] = c; printf("后缀表达式数组中的内容为:%c,j=%d\n",finalExp[j],j); j++; }else break;//如果栈中的优先级低,则不需要继续判断,退出循环 } //将新读到的运算符入栈 Push(&s,exp[i]); }else{ printf("运算符非法,停止运行!\n"); break; } } i++; } //当表达式读完之后,需要将栈中剩余的运算符依次出栈到后缀表达式数组中 while(!IsStackEmpty(&s)){ Pop(&s,&c); finalExp[j] = c; printf("后缀表达式数组中的内容为:%c,j=%d\n",finalExp[j],j); j++; } finalExp[j] = '\0'; } //10.后缀表达式求值 float EvaluateFinalExp(char *finalExp){ ValueStack v; InitValueStack(&v,MAXSIZE); float num; int i = 0; while(finalExp[i] != '\0'){ //依次读取后缀表达式的内容,遇到数字则转换成对应的浮点数再入栈,遇到运算符,出栈两个元素,计算结果,并将结果入栈 if(IsNum(finalExp[i])){ num = finalExp[i] - '0'; PushValue(&v,num); printf("读到第%d个元素%c,转换为数值%f\n",i,finalExp[i],num); }else{ switch(finalExp[i]){ case '+': v.data[v.top - 1] = v.data[v.top - 1] + v.data[v.top]; v.top--; break; case '-': v.data[v.top - 1] = v.data[v.top - 1] - v.data[v.top]; v.top--; break; case '*': v.data[v.top - 1] = v.data[v.top - 1] * v.data[v.top]; v.top--; break; case '/': if(v.data[v.top] != 0) v.data[v.top - 1] = v.data[v.top - 1] / v.data[v.top]; else{ printf("除0错\n"); exit(0); } v.top--; break; default: break; } printf("现在栈顶元素是%f\n",v.data[v.top]); } i++; } return v.data[v.top]; } int main(int argc, char **argv) { char exp[100]; char finalExp[100]; printf("请输入正确的中缀表达式,按回车结束:\n"); scanf("%s",exp); MidToFinal(exp,finalExp); printf("后缀表达式为:%s\n",finalExp); printf("表达式结果是:%f\n",EvaluateFinalExp(finalExp)); return 0; }
文章来源: 课程设计