(编译原理)逆波兰式算法的源代码.docx

上传人:doc321 文档编号:12898705 上传时间:2021-12-07 格式:DOCX 页数:13 大小:201.48KB
返回 下载 相关 举报
(编译原理)逆波兰式算法的源代码.docx_第1页
第1页 / 共13页
(编译原理)逆波兰式算法的源代码.docx_第2页
第2页 / 共13页
(编译原理)逆波兰式算法的源代码.docx_第3页
第3页 / 共13页
(编译原理)逆波兰式算法的源代码.docx_第4页
第4页 / 共13页
(编译原理)逆波兰式算法的源代码.docx_第5页
第5页 / 共13页
亲,该文档总共13页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述

《(编译原理)逆波兰式算法的源代码.docx》由会员分享,可在线阅读,更多相关《(编译原理)逆波兰式算法的源代码.docx(13页珍藏版)》请在三一文库上搜索。

1、一.实验目的1 深入理解算符优先分析法2 掌握 FirstVt 和 LastVt 集合的求法有算符优先关系表的求法3 掌握利用算符优先分析法完成中缀表达式到逆波兰式的转化二.实验内容及要求将非后缀式用来表示的算术表达式转换为用逆波兰式来表示的算术表达式,并计 算用逆波兰式来表示的算术表达式的值。程序输入/输出示例:输出的格式如下:(1) 逆波兰式的生成及计算程序,编制人:姓名,学号,班级(2) 输入一以#结束的中缀表达式(包括+*/()数字#):在此位置输入符号串如(28+68)*2# (3)逆波兰式为: 28&68+2*(4)逆波兰式 28&68+2*计算结果为 192备注:

2、(1)在生成的逆波兰式中如果两个数相连则用&分隔,如 28 和 68,中间用&分隔; (2) 在此位置输入符号串为用户自行输入的符号串。注意:1.表达式中允许使用运算符(+-*/)、分割符(括号)、数字,结束符#;2. 如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);3. 对学有余力的同学,测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照;三.实验过程1、逆波兰式定义将运算对象写在前面,而把运算符号写在后面。用这种表示法表示的表达式也称做后缀式。逆波兰式的特点在于运算对象顺序不变,运

3、算符号位置反映运算顺序。采用逆波兰式可以很好的表示简单算术表达式,其优点在于易于计算机处理表达式。 2、产生逆波兰式的前提中缀算术表达式3、逆波兰式生成的实验设计思想及算法输入一个中缀式表示的简单运算表达式 #入栈sym=当前输入符号sym 是数字吗?否栈顶运算符优先 级低于 sym 吗?否是是对数字进行处理,形成一个数字串将向前看符号入栈栈顶运算符出栈栈顶运算符与 sym 优先级相等吗?否是栈顶是 ( 且 sym 为)吗否是是将 栈 顶 运 算 符 弹出,且输出栈顶运算符优先 级高于 sym 吗否出错处理程序结束(1) 首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。(2)

4、 读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多 加上了优先级最低的特殊符号“#”。(3) 从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析 到该数字串的结束并将该数字串直接输出。(4) 如果不是数字,该字符则是运算符,此时需比较优先关系。做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。(5) 重复上述操作 (1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算

5、术表达式转化为逆波兰表示的简单算术表达式。 3、逆波兰式计算的实验设计思想及算法读入一个逆波兰算术表达式sym=当前输入符号将该字符入栈sym 是运算符吗?是根据运算符的特点从栈顶部取否Sym=#是程序结束否出若干个运算对象进行该运算 将运算结果入栈(1) 构造一个栈,存放运算对象。(2) 读入一个用逆波兰式表示的简单算术表达式。(3) 自左至右扫描该简单算术表达式并判断该字符,如果该字符是运算对象,则将该字符入栈。若是运算符,如果此运算符是二目运算符,则将对栈顶部的两个运算对象进行该运算,将运算结果入栈,并且将执行该运算的两个运算对象从栈顶弹出。如果该字符是一目运算符,则对栈顶部的元素实施该

6、运算,将该栈顶部的元素弹出,将运算结 果入栈。(4)重复上述操作直至扫描完整个简单算术表达式的逆波兰式,确定所有字符都得 到正确处理,我们便可以求出该简单算术表达式的值。4.实验的源程序代码如下:#include<stdio.h>#include<math.h>#define max 100char exmax; /*存储后缀表达式*/void trans() /*将算术表达式转化为后缀表达式*/char strmax; /*存储原算术表达式*/char stackmax; /*作为栈使用*/char ch;int sum,i,j,t,top=0;printf(&quo

7、t;*n");printf("*输入一个求值的表达式,以#结束。*n");printf("*n"); printf("算数表达式:");i=0; /*获取用户输入的表达式*/ doi+;scanf("%c",&stri);while(stri!='#' && i!=max);sum=i;t=1;i=1;ch=stri;i+;while(ch!='#')switch(ch)case '(': /*判定为左括号*/ top+;stackt

8、op=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='*

9、'|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;j<

10、sum;j+)printf("%c",strj);printf("nt 后缀表达式:",ex);for(j=1;j<t;j+)/*判定为数字*/printf("%c",exj);void compvalue() /*计算后缀表达式的值*/ float stackmax,d; /*作为栈使用*/char ch;int t=1,top=0; /*t 为 ex 下标,top 为 stack 下标*/ ch=ext;t+;while(ch!='#')switch(ch)case '+':stacktop-

11、1=stacktop-1+stacktop;top-;break;case '-':stacktop-1=stacktop-1-stacktop;top-;break;case '*':stacktop-1=stacktop-1*stacktop;top-;break;case '/':if(stacktop!=0)stacktop-1=stacktop-1/stacktop;elseprintf("nt 除零错误!n");exit(0); /*异常退出*/top-;break;default:d=0;while(ch>

12、='0'&&ch<='9')d=10*d+ch-'0' /*将数字字符转化为对应的数值*/ ch=ext;t+;top+;stacktop=d;ch=ext;t+;printf("nt 计算结果:%gn",stacktop);main()trans();compvalue();5.程序的运行结果如下:四.实验总结(心得)通过本实验的学习,主要掌握了逆波兰式算法的含义,结合书本知识,让我更加清楚此算法实现的主要过程,以及使用该算法的好处,通过对程序实现的分析,对于逆波兰式算法的 细节了解的更加清楚,从中学到了很多的东西。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1