我们在数学中常见的计算式,例如2+(3*4)叫做中缀表达式。表达式中涉及到了多个运算符,而运算符之间是有优先级的。计算机在计算并且处理这种表达式时,需要将中缀表达式转换成后缀表达式,然后再进行计算。
中缀表达式转后缀表达式遵循以下原则:
1.遇到操作数,直接输出;
2.栈为空时,遇到运算符,入栈;
3.遇到左括号,将其入栈;
4.遇到右括号,执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出;
5.遇到其他运算符'+''-''*''/'时,弹出所有优先级大于或等于该运算符的栈顶元素,然后将该运算符入栈;
6.最终将栈中的元素依次出栈,输出。
经过上面的步骤,得到的输出既是转换得到的后缀表达式。
举例:a+b*c+(d*e+f)*g ---------> abc*+de*f+g*+
遇到a,直接输出:
遇到+,此时栈为空,入栈:
遇到b,直接输出:
遇到*,优先级大于栈顶符号优先级,入栈:
遇到c,输出:
遇到+,目前站内的*与+优先级都大于或等于它,因此将栈内的*,+依次弹出并且输出,并且将遇到的这个+入栈:
遇到(,将其入栈:
遇到d,直接输出:
遇到*,由于*的优先级高于处在栈中的(,因此*入栈:
遇到e,直接输出:
遇到+,栈顶的*优先级高于+,但是栈内的(低于+,将*出栈输出,+入栈:
遇到f,直接输出:
遇到),弹出栈顶元素并且输出,直到弹出(才结束,在这里也就是弹出+输出,弹出(不输出:
遇到*,优先级高于栈顶+,将*入栈:
遇到g,直接输出:
此时已经没有新的字符了,依次出栈并输出操作直到栈为空:
明白了这个过程,现在就需要用代码实现了。对于各种运算符的优先级,可以使用整数来表示运算符的级别。可以定义一个函数来返回各种符号的优先级数字:
- intGetPrecedence(charc,intflag)
- {
- if(c=='+'||c=='-')
- {
- return1;
- }
- elseif(c=='*'||c=='/')
- {
- return2;
- }
- elseif(c=='('&&flag==0)
- {
- return0;
- }
- elseif(c=='('&&flag==1)
- {
- return3;
- }
- else
- {
- fprintf(stderr,"Inputcharisinvalid!\n");
- return-1;
- }
- }
还可以定义一个函数来判断当前遇到的是运算符还是操作数:
- intIsOperator(charc)
- {
- if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')')
- {
- return0;
- }
- else
- {
- return1;
- }
- }
完整代码:
- #include<stdio.h>
- #include<stdlib.h>
- #defineElementTypechar
- typedefstructNode*PtrToNode;
- typedefPtrToNodeStack;
- typedefstructNode
- {
- ElementTypeElement;
- PtrToNodeNext;
- };
- intIsEmpty(StackS);
- StackCreateStack();
- voidDisposeStack(StackS);
- voidMakeEmpty(StackS);
- voidPush(ElementTypeX,StackS);
- ElementTypeTop(StackS);
- voidPop(StackS);
- intIsEmpty(StackS)
- {
- returnS->Next==NULL;
- }
- StackCreateStack()
- {
- StackS=malloc(sizeof(structNode));
- if(S==NULL)
- {
- printf("Noenoughmemory!");
- returnNULL;
- }
- S->Next=NULL;
- MakeEmpty(S);
- returnS;
- }
- voidMakeEmpty(StackS)
- {
- if(S==NULL)
- {
- printf("UseCreateStackFirst!");
- }
- else
- {
- while(!IsEmpty(S))
- {
- Pop(S);
- }
- }
- }
- voidPush(ElementTypeX,StackS)
- {
- PtrToNodeTmp;
- Tmp=malloc(sizeof(structNode));
- if(Tmp!=NULL)
- {
- Tmp->Element=X;
- Tmp->Next=S->Next;
- S->Next=Tmp;
- }
- else
- {
- printf("Outofspace!");
- }
- }
- voidPop(StackS)
- {
- if(IsEmpty(S))
- {
- printf("TheStackisEmpty!");
- }
- else
- {
- PtrToNodeTmp=S->Next;
- S->Next=Tmp->Next;
- free(Tmp);
- }
- }
- ElementTypeTop(StackS)
- {
- if(IsEmpty(S))
- {
- printf("Thestackisempty!");
- return0;
- }
- else
- {
- returnS->Next->Element;
- }
- }
- intGetPrecedence(charc,intflag)
- {
- if(c=='+'||c=='-')
- {
- return1;
- }
- elseif(c=='*'||c=='/')
- {
- return2;
- }
- elseif(c=='('&&flag==0)
- {
- return0;
- }
- elseif(c=='('&&flag==1)
- {
- return3;
- }
- else
- {
- fprintf(stderr,"Inputcharisinvalid!\n");
- return-1;
- }
- }
- intIsOperator(charc)
- {
- if(c=='+'||c=='-'||c=='*'||c=='/'||c=='('||c==')')
- {
- return0;
- }
- else
- {
- return1;
- }
- }
- charOutput[50];
- char*InfixToPostfix(char*ch,StackS)
- {
- intindex=0;
- charc;
- while((c=*ch)!='\0')
- {
- if(IsOperator(c)==1)
- {
- Output[index++]=c;
- ch++;
- }
- else
- {
- if(IsEmpty(S))
- {
- Push(c,S);
- ch++;
- continue;
- }
- else
- {
- if(c==')')
- {
- while(!IsEmpty(S)&&Top(S)!='(')
- {
- Output[index++]=Top(S);
- Pop(S);
- }
- Pop(S);
- ch++;
- continue;
- }
- else
- {
- intoutPrecedence=GetPrecedence(c,1);
- while(!IsEmpty(S)&&GetPrecedence(Top(S),0)>=outPrecedence)
- {
- Output[index++]=Top(S);
- Pop(S);
- }
- Push(c,S);
- ch++;
- continue;
- }
- }
- }
- }
- while(!IsEmpty(S))
- {
- Output[index++]=Top(S);
- Pop(S);
- }
- Output[index]='\0';
- returnOutput;
- }
- intmain(void)
- {
- StackS=CreateStack();
- char*charSequence="1+2*3+(4*5+6)*7";
- chartmp;
- char*out=InfixToPostfix(charSequence,S);
- while((tmp=*out)!='\0')
- {
- printf("%c",tmp);
- out++;
- }
- printf("\n");
- return0;
- }
分享到:
相关推荐
/*程序由本人编译,并且经过多次测试,正确无误!目前该转换算法只支持数字在0至9之间的+-*/四元运算转换.*/ /**************程序员信息 ***************东北大学*******************东大很厉害**************** ...
先写词法分析的源文件,用正则表达式表示出需要识别的字符,例如数字,乘法,加法和括号,如果识别到其他非法字符需要报错,用flex生成lex.yy.c文件。语法分析用LR方法进行语法分析,LR方法需要先根据文法构造自动机...
数据结构的中缀表达式转后缀表达式,通过C++语言实现。使用堆栈方法进行转换,能正确运算包含括号、加、减、乘、除复合运算,如(1+2)*3-1.8*(18/(7+2)) = 8.2。
c语言实现中缀表达式转后缀表达式并求得计算结果,用顺序栈结构。 当输入者输入错误信息的时候需要报错,并说明错误的种类。
利用C语言实现中缀表达式转化为后缀表达式!!利用栈。
数据结构算法:中缀表达式转化为后缀表达式.doc 详细的论述和代码!
编译系统对中缀表达式的处理方法是先把它转换为后后缀表达式.在后缀表达式中,运算符位于两个操作数的后面,并且没有括号,其运算符的次序就是其执行运算的次序。后缀表达式计算过程的规则非常简单:从左到右依次扫描,...
一个简单的算法,利用栈实现中缀表达式与后缀表达式的转换
用栈实现中缀表达式转为后缀表达式,规定了各个符号的优先级,可以说是对栈概念的深入理解
数据结构 中缀表达式转后缀表达式算法的实现。
用户输入中缀表达式,程序输出后缀表达式并输出计算结果
c语言实现中缀表达式向后缀表达式转换 分类:算法+数据结构
问题描述 中缀表达式就是我们通常所书写的数学...要求:使用栈数据结构实现 ,输入的中缀表达式以#号结束 输入 整数N。表示下面有N个中缀表达式 N个由单个字母和运算符构成的表达式 输出 N个后缀表达式。
栈实现中缀表达式到后缀表达式的转换 InfixToSuffix 用C语言编写 code blocks开发
中缀表达式转后缀表达式,并进行计算; 支持: 支持函数: Abs 绝对值 Power 幂 Sqr 平方 Sqrt 平方根 Abs Sqr Sqrt 需要加括号 Power不需要 * 后缀运算符: * 第1级: () 从左到右 * 算出运算符: * 第4级:* \ % 从...
08.中缀表达式转换后缀表达式算法.ppt
中缀表达式转后缀生产表达式二叉树,并在控制台中画出。