波兰式转换为逆波兰式.docx_第1页
波兰式转换为逆波兰式.docx_第2页
波兰式转换为逆波兰式.docx_第3页
波兰式转换为逆波兰式.docx_第4页
波兰式转换为逆波兰式.docx_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

波兰式转换为逆波兰式(中缀表达式转换为后缀表达式)逆波兰式(Reverse Polish notation,RPN,或逆波兰记法),也叫后缀表达式(将运算符写在操作数之后)一、定义一个表达式E的后缀形式可以如下定义:(1)如果E是一个变量或常量,则E的后缀式是E本身。(2)如果E是E1 op E2形式的表达式,这里op是如何二元操作符,则E的后缀式为E1E2 op,这里E1和E2分别为E1和E2的后缀式。(3)如果E是(E1)形式的表达式,则E1的后缀式就是E的后缀式。如:我们平时写a+b,这是中缀表达式,写成后缀表达式就是:ab+(a+b)*c-(a+b)/e的后缀表达式为:(a+b)*c-(a+b)/e(a+b)*c)(a+b)/e)-(a+b)c*)(a+b)e/)-(ab+c*)(ab+e/)-ab+c*ab+e/-二、算法实现将一个普通的中序表达式转换为逆波兰表达式的一般算法是:首先需要分配2个栈,一个作为临时存储运算符的栈S1(含一个结束符号),一个作为输入逆波兰式的栈S2(空栈),S1栈可先放入优先级最低的运算符#,注意,中缀式应以此最低优先级的运算符结束。可指定其他字符,不一定非#不可。从中缀式的左端开始取字符,逐序进行如下步骤:(1)若取出的字符是操作数,则分析出完整的运算数,该操作数直接送入S2栈(2)若取出的字符是运算符,则将该运算符与S1栈栈顶元素比较,如果该运算符优先级大于S1栈栈顶运算符优先级,则将该运算符进S1栈,否则,将S1栈的栈顶运算符弹出,送入S2栈中,直至S1栈栈顶运算符低于(不包括等于)该运算符优先级,则将该运算符送入S1栈。(3)若取出的字符是“(”,则直接送入S1栈栈顶。(4)若取出的字符是“)”,则将距离S1栈栈顶最近的“(”之间的运算符,逐个出栈,依次送入S2栈,此时抛弃“(”。(5)重复上面的14步,直至处理完所有的输入字符(6)若取出的字符是“#”,则将S1栈内所有运算符(不包括“#”),逐个出栈,依次送入S2栈。完成以上步骤,S2栈便为逆波兰式输出结果。不过S2应做一下逆序处理。便可以按照逆波兰式的计算方法计算了!三、作用实现逆波兰式的算法,难度并不大,但为什么要将看似简单的中序表达式转换为复杂的逆波兰式?原因就在于这个简单是相对人类的思维结构来说的,对计算机而言中序表达式是非常复杂的结构。相对的,逆波兰式在计算机看来却是比较简单易懂的结构。因为计算机普遍采用的内存结构是栈式结构,它执行先进后出的顺序。四、举例下面以(a+b)*c为例子进行说明:(a+b)*c的逆波兰式为ab+c*,假设计算机把ab+c*按从左到右的顺序压入栈中,并且按照遇到运算符就把栈顶两个元素出栈,执行运算,得到的结果再入栈的原则来进行处理,那么ab+c*的执行结果如下:1)a入栈(0位置)2)b入栈(1位置)3)遇到运算符“+”,将a和b出栈,执行a+b的操作,得到结果d=a+b,再将d入栈(0位置)4)c入栈(1位置)5)遇到运算符“*”,将d和c出栈,执行d*c的操作,得到结果e,再将e入栈(0位置)经过以上运算,计算机就可以得到(a+b)*c的运算结果e了。逆波兰式除了可以实现上述类型的运算,它还可以派生出许多新的算法,数据结构,这就需要灵活运用了。逆波兰式只是一种序列体现形式。五、程序实现/逆波兰式 (C语言版)#include#include#include#include#define max 100char exmax; /*存储后缀表达式*/void trans() /*将算术表达式转化为后缀表达式*/char strmax; /*存储原算术表达式*/char stackmax; /*作为栈使用*/char ch;int sum,i,j,t,top=0;printf(*n);printf(*输入一个求值的表达式,以#结束。*n);printf(*n);printf(算数表达式:);i=0; /*获取用户输入的表达式*/doi+;cinstri;/*此步我用的是C+ C语言的话在后面 之所以用这个有一点区别 都*/scanf(%c,&stri);while(stri!=# & i!=max);sum=i;t=1;i=1;ch=stri;i+;/while(ch!=#)switch(ch)case (: /*判定为左括号*/top+;stacktop=ch;break;case ): /*判定为右括号*/while(stacktop!=()ext=stacktop;top-;t+;top-;break;case +: /*判定为加减号*/case -:while(top!=0&stacktop!=()ext=stacktop;top-;t+;top+;stacktop=ch;break;case *: /*判定为乘除号*/case /:while(stacktop=*|stacktop=/)ext=stacktop;top-;t+;top+;stacktop=ch;break;case :break;default:while(ch=0&ch=9) /*判定为数字*/ext=ch;t+;ch=stri;i+;i-;ext= ;t+;ch=stri;i+;while(top!=0)ext=stacktop;t+;top-;ext= ;printf(nt原来表达式:);for(j=1;jsum;j+)printf(%c,strj);printf(nt逆波兰式:,ex);for(j=1;j=0&ch=precede(ch)Pop(s1,cj+);w=Top(s1);Push(s1,ch);ch=ei+;else/while(ch=a)|(ch=A)cj+=ch;ch=ei+;/cj+= ;Pop(s1,ch);while(ch!=)cj+=ch;Pop(s1,ch);/cj+=;cj+=0;return c;还有一种方法,用2叉树.二叉树法将最终进行的运算符记为根节点,将两边的表达式分别记为左右子树,依次进行直到所有的运算符与数字或字母标在一棵二叉树上。然后对二叉树进行后序遍历即可。其中代表一个标识,代表预算法,名字Q代表变量(如int a,b等),算法用到三个栈:a栈,b栈,in栈。其中a栈用来存储逆波兰式,b用来存储号和运算符,in栈为输入栈。第一竖排为b栈中符号,第一横排为输入栈中符号。pop(in)为输入栈栈顶元素出栈,pop(a,Q)为Q入a栈,NEXT算法即为进行下一轮循环,其中12为算符优先级,如“+”和“-”“*”和“/”。pop(b,B),push(b,B)中B为临时变量,用来存储出栈的元素。stop为算法结束。算法开始时,现将如b栈,输入栈以#号结尾。?输入流bs-1名字Q?(2)?#POP(in);PUSH(a,Q)NEXTPOP(in);PUSH(b,)NEXTPOP(in)PUSH(b,2)NEXTPOP(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论