中缀表达式转换成后缀表达式
2011-09-03 11:27
405 查看
例如:
中缀表达式 a+b*c+(d*e+f)*g
转换成后缀表达式,正确答案是;
a b c * + d e * f + g * +
算法分析:
当读到一个操作数的时候,立即把它放在输出中,如果遇到操作符时,存放在栈中,不立即输出;当遇到左圆括号时我们也要将其推入栈中,我们从一个空栈开始计算;
如果见到一个右括号,那么就将栈元素弹出,将弹出的符号输出直到我们遇到一个(对应的)左括号,但是这个左括号只被弹出,并不输出 ;
如果我们见到任何其他的符号( "+", "*", "(" ),那么我们从栈中弹出栈元素直到发现优先级更低的元素为止(也就是弹出比它优先级高的或相等的元素);有一个例外:除非是在处理一个")"的时候,否则我们绝不从栈中移走"(",对于这种操作,")"的优先级最低,而"("的优先级最高。当从栈弹出元素的工作完成后,我们再将操作符压入栈中。
最后,如果我们读到输入的末尾,我们将栈元素弹出直到该栈变成空栈,将符号写到输出中。
我写的代码,需要改进,请高人指点。
stack.h
stack.c
main.c
中缀表达式 a+b*c+(d*e+f)*g
转换成后缀表达式,正确答案是;
a b c * + d e * f + g * +
算法分析:
当读到一个操作数的时候,立即把它放在输出中,如果遇到操作符时,存放在栈中,不立即输出;当遇到左圆括号时我们也要将其推入栈中,我们从一个空栈开始计算;
如果见到一个右括号,那么就将栈元素弹出,将弹出的符号输出直到我们遇到一个(对应的)左括号,但是这个左括号只被弹出,并不输出 ;
如果我们见到任何其他的符号( "+", "*", "(" ),那么我们从栈中弹出栈元素直到发现优先级更低的元素为止(也就是弹出比它优先级高的或相等的元素);有一个例外:除非是在处理一个")"的时候,否则我们绝不从栈中移走"(",对于这种操作,")"的优先级最低,而"("的优先级最高。当从栈弹出元素的工作完成后,我们再将操作符压入栈中。
最后,如果我们读到输入的末尾,我们将栈元素弹出直到该栈变成空栈,将符号写到输出中。
我写的代码,需要改进,请高人指点。
stack.h
#ifndef STACK_H_ #define STACK_H_ struct StackRecord; typedef struct StackRecord * STACK; typedef char ElementType; struct StackRecord { int Capacity; int TopOfStack; ElementType * array; }; int IsEmpty(STACK S); //判断栈是否为空 int IsFull(STACK S); //判断栈是否已满 STACK CreateStack(int MaxElements); //创建空栈 void DisposeStack(STACK S); //释放栈 void MakeEmpty(STACK S); //将栈初始化为空的状态 void Push(ElementType X,STACK S); //压入栈 ElementType Top(STACK S); //返回栈顶的数据 void Pop(STACK S); //压出栈 ElementType TopAndPop(STACK S); //返回栈顶的数据并压出栈 int size(char str); //返回操作符的优先级大小 #endif #define EmptyTOS (-1) #define MinStackSize (5)
stack.c
#include <stdio.h> #include <stdlib.h> #include "stack.h" STACK CreateStack(int MaxElements) { STACK S; if(MaxElements<MinStackSize) { puts("栈的大小太小"); exit(1); } S=(STACK)malloc(sizeof(struct StackRecord)); if(S==NULL) { puts("内存不足"); exit(1); } S->array=(ElementType *)malloc(sizeof(ElementType)*MaxElements); if(S->array==NULL) { puts("内存不足"); exit(1); } S->Capacity=MaxElements; MakeEmpty(S); return S; } void DisposeStack(STACK S) { if(S!=NULL) { free(S->array); free(S); } } int IsEmpty(STACK S) { return S->TopOfStack==EmptyTOS; } int IsFull(STACK S) { return S->TopOfStack==S->Capacity; } void MakeEmpty(STACK S) { S->TopOfStack=EmptyTOS; } void Push(ElementType X,STACK S) { if(IsFull(S)) { puts("栈满了"); exit(1); } else S->array[++S->TopOfStack]=X; } ElementType Top(STACK S) { if(!IsEmpty(S)) return S->array[S->TopOfStack]; puts("空栈"); return 0; } void Pop(STACK S) { if(IsEmpty(S)) { puts("空栈"); exit(1); } else S->TopOfStack--; } ElementType TopAndPop(STACK S) { if(!IsEmpty(S)) return S->array[S->TopOfStack--]; puts("空栈"); return 0; } int size(char str) { switch(str) { case ')': return 0; break; case '+': case '-': return 1; break; case '*': case '/': return 2; break; case '(': return 3; break; } }
main.c
#include <stdio.h> #include <string.h> #include "stack.h" #define MAXSTACK 100 int main(void) { char string1[40]; char string2[40]={0}; int i,j=0; size_t len; char a,tmp; STACK stack; //创建栈 stack=CreateStack(MAXSTACK); //获取表达式 printf("输入表达式:\n"); gets(string1); //计算表达式的字符长度 len=strlen(string1); //中缀转后缀 for(i=0;i<len;i++) { //将数字输出到string2数组中 while(string1[i]>='0' && string1[i]<='9') { string2[j++]=string1[i++]; } //判断是否已超出长度 if(i<len) { a=string1[i]; string2[j++]=' '; //空栈时,压入第一个操作符 if(IsEmpty(stack)) { Push(a,stack); } else if(size(a)>size(Top(stack))) //如果当前操作符的优先级大于栈顶的操作符就推入栈 Push(a,stack); else if(Top(stack)=='(') //如果栈顶操作符是(,就推入当前操作符到栈中 Push(a,stack); else //压出栈中比当前操作符的优先级高的所有操作符,(除当前操作符是)时,特殊处理 { while(size(a)<=size(Top(stack))) { if(Top(stack)=='(' && a==')') //当栈顶是( 且当前操作符是) 时 压出栈顶 (,不存储在数组string2中 { Pop(stack); break; } else if(Top(stack)=='(') //当栈顶是(时,退出当前循环后,压入当前操作符 { break; } else if(a==')') //如果当前操作符是),那就把栈中)上面的操作符都压出栈 { if(size(Top(stack))<3) { string2[j++]=TopAndPop(stack); string2[j++]=' '; } else { Pop(stack); break; } } else //压出栈中比当前操作符的优先级高的所有操作符 { string2[j++]=TopAndPop(stack); string2[j++]=' '; } if(IsEmpty(stack)) break; } if(a!=')') //压入当前操作符到栈中 { Push(a,stack); } } } } while(!IsEmpty(stack)) //如果栈非空,把里面的数据都压出来放在数组string2中 { string2[j++]=' '; string2[j++]=TopAndPop(stack); } printf("%s\n",string2); }
相关文章推荐
- 中缀和后缀表达式之间的转换
- 中缀表达式到后缀表达式的转换C++实现
- [栈和队列]从中缀向后缀转换表达式
- 中缀表达式转换为后缀表达式,计算后缀表达式
- 中缀表达式转换为后缀表达式
- 二叉树中缀表达式到后缀表达式的转换
- 栈的应用 平衡符号 后缀表达式 中缀到后缀的转换
- [栈和队列]从中缀向后缀转换表达式
- 中缀表达式转换成后缀表达式
- 中缀表达式到后缀表达式的转换
- [栈和队列]从中缀向后缀转换表达式
- 漫谈栈队列及后缀表达式,后缀中缀表达式间的转换
- 中缀表达式转换成前缀表达式和后缀表达式
- 面试题77:前缀、中缀、后缀表达式的相互转换
- PTA 表达式转换 算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间。请设计程序将中缀表达式转换为后缀表达式。
- 八、通过中缀计算表达式转换成后缀计算表达式
- 中缀后缀表达式的转换
- 表达式 中缀 后缀 转换
- 数据结构之栈----PTA题目7-20表达式转换(中缀转后缀)
- 中缀/后缀表达式转换-使用四则混合运算表达式生成树