1、中缀(infix)表达式(expression)转换为后缀(postfix)表达式:(注:为了方便起见,表达式对象的输入输出均用空格分开)
首先需要从头到尾读取中缀表达式中的每一个对象,建立一个堆栈
(1)遇到操作数,直接输出;
(2)遇到运算符,当该运算符大于栈顶运算符的优先级时,将该运算符压入栈中;如果该运算符的优先级小于或等于栈顶元素的优先级时,将栈顶元素弹出并输出,并比较新的
栈顶运算符,知道该运算符大于栈顶运算符,并将该运算符压入栈中。
(3)遇到左括号,将其压入栈中;
(4)遇到右括号,将括号内的运算符依次弹出并输出,直到遇到左括号(左括号也出栈,但不输出)。
(5)若中缀表达式中的对象处理完毕,则将栈中剩余的运算符弹出并输出。
代码如下:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<stdbool.h> 4 #include<ctype.h> 5 #define MAXOP 100 6 typedef struct SNode{ 7 char *Data; 8 int Top; 9 int Maxsize; 10 }Stack; 11 12 Stack *CreateStack(int Maxsize) 13 { 14 Stack *S; 15 S=(Stack *)malloc(sizeof(struct SNode)); 16 S->Top=-1; 17 S->Data=(char *)malloc(Maxsize * sizeof(char)); 18 S->Maxsize=Maxsize; 19 return S; 20 } 21 22 bool IsFull(Stack *S) 23 { 24 return (S->Top==S->Maxsize-1); 25 } 26 27 void Push(Stack *S,char op) 28 { 29 if(!IsFull(S)) 30 { 31 S->Data[++(S->Top)]=op; 32 } 33 } 34 35 bool IsEmpty(Stack *S) 36 { 37 return (S->Top==-1); 38 } 39 40 char Pop(Stack *S) 41 { 42 char op; 43 if (!IsEmpty(S)) 44 { 45 op=S->Data[(S->Top)--]; 46 } 47 return op; 48 } //以上是建立栈,及栈的基本操作 49 50 /* 取出栈顶元素的函数 */ 51 char Top(Stack *S) 52 { 53 char op; 54 if (!IsEmpty(S)) 55 { 56 op=S->Data[(S->Top)]; 57 } 58 return op; 59 } 60 61 typedef enum {num,opr,end}Type; 62 63 /* 扫描中缀表达式中的每个对象,将其存在str数组中 。start传进去的是地址。str数组在每次函数调用的过程中其值会不断的变化*/ 64 Type GetOp(char *Expr,int *start,char *str) 65 { 66 int i=0; 67 while ((str[0]=Expr[(*start)++])==' '); //跳过表达式对象前的空格 68 while (str[i]!=' ' && str[i]!='\0') //遇到空格或结尾标识符,结束一个对象的获取 69 { 70 str[++i]=Expr[(*start)++]; //表达式存在str中 71 } 72 if (str[i]=='\0')(*start)--; //start指向表达式末尾结束符'\0' 73 str[i]='\0'; //结束一个对象的获取 74 75 if (i==0) return end; 76 else if (isdigit(str[0])||isdigit(str[1])) return num; //考虑到类似于".3"这样的对象 77 else return opr; 78 } 79 /* 优先级函数 */ 80 int Prior(char op) 81 { 82 switch (op) 83 { 84 case '*': 85 case '/': return 2; 86 case '+': 87 case '-': return 1; 88 case '(': return 0; //当左括号压入栈中后,其优先级变得最低 89 } 90 } 91 /*核心,中缀表达式转换为后缀表达式*/ 92 void PrintPostfixExp(char *Expr) 93 { 94 int start=0; 95 Type T; 96 char str[MAXOP]; 97 char op1,op2; 98 Stack *S; 99 S=CreateStack(MAXOP); 100 while((T=GetOp(Expr,&start,str))!=end) 101 { 102 if (T==num)printf("%s ",str); //数字直接输出 103 else 104 { 105 switch(str[0]) 106 { 107 case '(':Push(S,str[0]);break; //左括号直接压入栈中 108 case ')': 109 { 110 while(Top(S)!='(')printf("%c ",Pop(S)); //括号内的操作符弹出并输出 111 Pop(S); //弹出左括号 112 break; 113 } 114 case '+': 115 case '-': 116 case '*': 117 case '/': 118 { 119 if (IsEmpty(S)){Push(S,str[0]);break;} //栈是空的时候,直接压入栈中 120 else 121 { 122 op1=Top(S); 123 while (Prior(str[0])<=Prior(op1)) //依次将该对象和栈中的元素进行比较,直到栈不为空并且该操作符的优先级大于栈顶操作符优先级 124 {printf("%c ",Pop(S)); 125 if (IsEmpty(S))op1=Top(S); //栈空时,退出循环 126 else break; 127 } 128 Push(S,str[0]); //将该运算符压栈 129 } 130 break; 131 } 132 133 } 134 } 135 } 136 while(!IsEmpty(S))printf("%c ",Pop(S)); //将栈中剩余的运算符弹出并输出 137 } 138 139 int main() 140 { 141 char Expr[MAXOP]; 142 gets(Expr); 143 PrintPostfixExp(Expr); 144 return 0; 145 }
2、求值
我是在“1”代码的基础上进行的改进,但强烈不建议这么做,因为我不知道怎么去处理出现了两个栈是冗杂重复的代码怎么解决
(1)当对象是数时,压入栈中;
(2)当对象是运算符时,从栈中弹出适当数量的运算符,进行运算并将结果压入栈中;
(3)处理完整个后缀表达式后,栈顶元素就是结果。
代码如下:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<stdbool.h> 4 #include<ctype.h> 5 #define MAXOP 100 6 /* 以下一大段是两个堆栈的定义及其基本操作*/ 7 8 //目前我只会C语言,没有什么更好的办法去解决这一段的冗杂 9 10 typedef struct SNode{ //第一个堆栈用来存放运算符 11 char *Data; 12 int Top; 13 int Maxsize; 14 }Stack; 15 16 Stack *CreateStack(int Maxsize) 17 { 18 Stack *S; 19 S=(Stack *)malloc(sizeof(struct SNode)); 20 S->Top=-1; 21 S->Data=(char *)malloc(Maxsize * sizeof(char)); 22 S->Maxsize=Maxsize; 23 return S; 24 } 25 26 bool IsFull(Stack *S) 27 { 28 return (S->Top==S->Maxsize-1); 29 } 30 31 void Push(Stack *S,char op) 32 { 33 if(!IsFull(S)) 34 { 35 S->Data[++(S->Top)]=op; 36 } 37 } 38 39 bool IsEmpty(Stack *S) 40 { 41 return (S->Top==-1); 42 } 43 44 char Pop(Stack *S) 45 { 46 char op; 47 if (!IsEmpty(S)) 48 { 49 op=S->Data[(S->Top)--]; 50 } 51 return op; 52 } 53 char Top(Stack *S) 54 { 55 char op; 56 if (!IsEmpty(S)) 57 { 58 op=S->Data[(S->Top)]; 59 } 60 return op; 61 } 62 63 typedef struct SNode1{ //第二个堆栈用来存放运算数 64 float *Data; 65 int Top; 66 int Maxsize; 67 }Stack1; 68 69 Stack1 *CreateStack1(int Maxsize) 70 { 71 Stack1 *S; 72 S=(Stack1 *)malloc(sizeof(struct SNode)); 73 S->Top=-1; 74 S->Data=(float *)malloc(Maxsize * sizeof(float)); 75 S->Maxsize=Maxsize; 76 return S; 77 } 78 79 bool IsFull1(Stack1 *S) 80 { 81 return (S->Top==S->Maxsize-1); 82 } 83 84 void Push1(Stack1 *S,float op) 85 { 86 if(!IsFull1(S)) 87 { 88 S->Data[++(S->Top)]=op; 89 } 90 } 91 92 bool IsEmpty1(Stack1 *S) 93 { 94 return (S->Top==-1); 95 } 96 97 float Pop1(Stack1 *S) 98 { 99 float op; 100 if (!IsEmpty1(S)) 101 { 102 op=S->Data[(S->Top)--]; 103 } 104 return op; 105 } 106 107 108 typedef enum {num,opr,end}Type; 109 110 Type GetOp(char *Expr,int *start,char *str) //获取每个对象 111 { 112 int i=0; 113 while ((str[0]=Expr[(*start)++])==' '); 114 while (str[i]!=' ' && str[i]!='\0') 115 { 116 str[++i]=Expr[(*start)++]; 117 } 118 if (str[i]=='\0')(*start)--; 119 str[i]='\0'; 120 121 if (i==0) return end; 122 else if (isdigit(str[0])||isdigit(str[1])) return num; 123 else return opr; 124 } 125 126 int Prior(char op) 127 { 128 switch (op) 129 { 130 case '*': 131 case '/': return 2; 132 case '+': 133 case '-': return 1; 134 case '(': return 0; 135 } 136 } 137 /* 运算函数 */ 138 void PushAns(Stack1 *S,char op) 139 { 140 float op1,op2; 141 if (!IsEmpty1(S))op1=Pop1(S); 142 if (!IsEmpty1(S))op2=Pop1(S); 143 switch (op) 144 { 145 case '+':Push1(S,op2+op1);break; 146 case '-':Push1(S,op2-op1);break; 147 case '*':Push1(S,op2*op1);break; 148 case '/':if (op2!=0.0)Push1(S,op2/op1);break; 149 } 150 } 151 152 float PrintPostfixExp(char *Expr) 153 { 154 int start=0; 155 Type T; 156 char str[MAXOP]; 157 char op1,op4; 158 float op2; 159 Stack *S; 160 Stack1 *S1; 161 S=CreateStack(MAXOP); 162 S1=CreateStack1(MAXOP); 163 while((T=GetOp(Expr,&start,str))!=end) 164 { 165 if (T==num) 166 {printf("%s ",str); 167 Push1(S1,atof(str)); //将数压入栈中 168 } 169 else 170 { 171 switch(str[0]) 172 { 173 case '(':Push(S,str[0]);break; 174 case ')': 175 { 176 while(Top(S)!='(') 177 { 178 op4=Pop(S); 179 printf("%c ",op4); 180 PushAns(S1,op4); //进行运算并将结果压入栈中 181 } 182 Pop(S); 183 break; 184 } 185 case '+': 186 case '-': 187 case '*': 188 case '/': 189 { 190 if (IsEmpty(S)){Push(S,str[0]);break;} 191 else 192 { 193 op1=Top(S); 194 while (Prior(str[0])<=Prior(op1)) 195 { 196 op4=Pop(S); 197 printf("%c ",op4); 198 PushAns(S1,op4); //进行计算并将结果压入栈中 199 if (!IsEmpty(S))op1=Top(S); 200 else break; 201 } 202 203 Push(S,str[0]); 204 } 205 break; 206 } 207 208 } 209 } 210 } 211 while(!IsEmpty(S)) 212 { 213 op4=Pop(S); 214 printf("%c ",op4); 215 PushAns(S1,op4); //最后进行运算并将结果压入栈中 216 } 217 printf("\n"); 218 printf("the ans is :"); 219 if(!IsEmpty1(S1))op2=Pop1(S1); //结果 220 free(S); 221 free(S1); 222 return op2; 223 } 224 225 int main() 226 { 227 char Expr[MAXOP]; 228 gets(Expr); 229 float op; 230 op=PrintPostfixExp(Expr); 231 printf("%.3f",op); 232 return 0; 233 }