用算法计算出算术表达式:(56-20)/(4+2)的值
2015-12-26 20:42
344 查看
①、先将算术表达式转换成后缀表达式;
②、然后对该后缀表达式求值;
③、编写主函数,得到计算结果。
四、实验总结
实验优点:
1.在起初分析算术表达式的运算规则,算术表达式所用到的数据结构,即栈,知道并会使用栈的基本运算,了解算术表达式求值的基本算法思想,操作数栈和算符栈的结合使用。于是开始着手编写程序,将上述已经明白的知识点通过程序展现出来,包括两种栈的定义,涉及到的栈的功能函数的设计,以及基本的算术表达式的简单计算。
2.熟悉了中缀表达式转换为后缀表达式的基本算法过程分为以下起步,其余类似。
1) 首先将左括号“(”压进栈,作为栈底元素;
2) 从左而右对算数表达式进行扫描,每次读入一个字符s1[i];
3) 若遇到数字或小数点,则立即写入s2[i],若遇算数运算符,将“ ”(空格)写入s2[i];
4) 遇到左括号“(”则压栈;
5) 若遇算术运算符,如果它们的优先级比栈顶元素高,则直接进栈,否则弹出栈顶元素输出到s2[i],直到新栈顶元素的优先级比它低,然后将它压栈;
6) 若遇到右括号“)”,则将栈顶元素输出到s2[i],直到栈顶元素为“(”,然后相互抵消;
7) 当扫描到“#”符号,表明表达式串已全部输入,将栈中的运算符全部输出到s2[i],并删除栈顶元素。
实验缺点:
1.虽然上述基本工作已经完成,但对于具体处理算术表达式时,出现了很多的语法问题,逻辑问题,包括:怎样区分算术表达式中的算符和操作数的问题,怎样进行优先级的判断和比较问题,怎样处理非法算符的问题;怎样处理非法操作数的问题,怎样处理括号匹配的问题,怎样处理操作数为多位数的问题,怎样处理当操作数从正整数范围扩充到实数范围时的问题,怎样处理具体调用功能函数时出现的问题,等等;这些问题困扰了我一部分时间,之后,经反复思考,反复查阅资料,反复浏览网络,同时与同学交流讨论,上述问题均得到了解决。
2.在编写代码的时候,大小写的问题相当重要,但是往往不太注重,从而导致调试出现错误;在检查函数的时候一定要注意MaxSize是否定义;这个是这几次实验中常出现的问题;在实验二中,在写要函数时,要明确的用0、1写出迷宫的整个布局,这样函数才会输出相应的位置;如果是直接复制ppt上的代码,会出现很多错误,需要去掉一些空格,修改格式。
实验需要改进的地方:
1.在解决算法设计过程中出现的难题之后,程序初步完成,但并不是到此为止,如何改进算法,如何提高算法的时间复杂度、空间复杂度,如何处理一些意想不到的错误和特有情况。
2.在编程过程中,为了增加程序的实用性,将程序适用范围扩大到了实数型,并增加了连续输入功能;
3.在编程过程中,为了增加程序的健壮性,在运算除法时,考虑到除数为“0”时的报错和及时退出;
4.在调试过程中,最初一下子出来程序就出错,为了方便检查错误,故在主函数中增加了检查后缀表达式是否转换正确的函数,并在每一步计算都跟踪结果是否正确;
5.开始写的时候经常忘记写主函数而去调试。并且由于其中的调用函数太多的原因。好多错误出现在括号问题上。并且由于调用函数多的原因常常不知将一个程序从哪里入手去写。还有就是在写主函数时经常忘了定义MaxSize。从而出现错误。
②、然后对该后缀表达式求值;
③、编写主函数,得到计算结果。
#include<stdio.h> #include<stdlib.h> #include<malloc.h> #include<iostream> #define MaxSize 50 //先将算术表达式转换成后缀表达式; struct { char ch; int pri; } lpri[]={{'=',0},{'(',1},{'*',5},{'/',5},{'+',3}, {'-',3},{')',6}}, rpri[]={{'=',0},{'(',6},{'*',4},{'/',4},{'+',2}, {'-',2},{')',1}}; int leftpri(char op) { int i; for (i=0;i<MaxOp;i++) if (lpri[i].ch==op) return lpri[i].pri; } int rightpri(char op) { int i; for (i=0;i<MaxOp;i++) if (rpri[i].ch==op) return rpri[i].pri; } bool InOp(char ch) { if (ch=='(' || ch==')' || ch=='+' || ch=='-' || ch=='*' || ch=='/') return true; else return false; } int Precede(char op1,char op2) { if (leftpri(op1)==rightpri(op2)) return 0; else if (leftpri(op1)<rightpri(op2)) return -1; else return 1; } //然后对该后缀表达式求值 void trans(char *exp,char postexp[]) { struct { char data[MaxSize]; int top; } op; int i=0; op.top=-1; op.top++; op.data[op.top]='='; while (*exp!='\0') { if (!InOp(*exp)) { while (*exp>='0' && *exp<='9') { postexp[i++]=*exp; exp++; } postexp[i++]='#'; } else switch(Precede(op.data[op.top],*exp)) { case -1: op.top++;op.data[op.top]=*exp; exp++; break; case 0: op.top--; exp++; break; case 1: postexp[i++]=op.data[op.top]; op.top--; break; } } //while (*exp!='\0') while (op.data[op.top]!='=') { postexp[i++]=op.data[op.top]; op.top--; } postexp[i]='\0'; } float compvalue(char exp[]) { struct { float data[MaxSize]; int top; } st; float d; char ch; int t=0; st.top=-1; ch=exp[t];t++; while (ch!='\0') { switch (ch) { case'+':st.data[st.top-1]= st.data[st.top-1]+st.data[st.top]; st.top--;break; case '-':st.data[st.top-1]= st.data[st.top-1]-st.data[st.top]; st.top--;break; case '*':st.data[st.top-1]= st.data[st.top-1]*st.data[st.top]; st.top--;break; case '/': if (st.data[st.top]!=0) st.data[st.top-1]= st.data[st.top-1]/st.data[st.top]; else { printf("\n\t除零错误!\n"); exit(0); } st.top--;break; default: d=0; while (ch>='0' && ch<='9') { d=10*d+ch-'0'; ch=exp[t];t++; } st.top++; st.data[st.top]=d; } ch=exp[t];t++; } return st.data[st.top]; } //编写主函数,得到计算结果 void main() { char exp[]="(56-20)/(4+2)"; char postexp[MaxSize]; trans(exp,postexp); printf("中缀表达式:%s\n",exp); printf("后缀表达式:%s\n",postexp); printf("表达式的值:%g\n",compvalue(postexp)); } 结果: 中缀表达式:(56-20)/(4+2) 后缀表达式:56#20#-4#2#+/ 表达式的值:6
四、实验总结
实验优点:
1.在起初分析算术表达式的运算规则,算术表达式所用到的数据结构,即栈,知道并会使用栈的基本运算,了解算术表达式求值的基本算法思想,操作数栈和算符栈的结合使用。于是开始着手编写程序,将上述已经明白的知识点通过程序展现出来,包括两种栈的定义,涉及到的栈的功能函数的设计,以及基本的算术表达式的简单计算。
2.熟悉了中缀表达式转换为后缀表达式的基本算法过程分为以下起步,其余类似。
1) 首先将左括号“(”压进栈,作为栈底元素;
2) 从左而右对算数表达式进行扫描,每次读入一个字符s1[i];
3) 若遇到数字或小数点,则立即写入s2[i],若遇算数运算符,将“ ”(空格)写入s2[i];
4) 遇到左括号“(”则压栈;
5) 若遇算术运算符,如果它们的优先级比栈顶元素高,则直接进栈,否则弹出栈顶元素输出到s2[i],直到新栈顶元素的优先级比它低,然后将它压栈;
6) 若遇到右括号“)”,则将栈顶元素输出到s2[i],直到栈顶元素为“(”,然后相互抵消;
7) 当扫描到“#”符号,表明表达式串已全部输入,将栈中的运算符全部输出到s2[i],并删除栈顶元素。
实验缺点:
1.虽然上述基本工作已经完成,但对于具体处理算术表达式时,出现了很多的语法问题,逻辑问题,包括:怎样区分算术表达式中的算符和操作数的问题,怎样进行优先级的判断和比较问题,怎样处理非法算符的问题;怎样处理非法操作数的问题,怎样处理括号匹配的问题,怎样处理操作数为多位数的问题,怎样处理当操作数从正整数范围扩充到实数范围时的问题,怎样处理具体调用功能函数时出现的问题,等等;这些问题困扰了我一部分时间,之后,经反复思考,反复查阅资料,反复浏览网络,同时与同学交流讨论,上述问题均得到了解决。
2.在编写代码的时候,大小写的问题相当重要,但是往往不太注重,从而导致调试出现错误;在检查函数的时候一定要注意MaxSize是否定义;这个是这几次实验中常出现的问题;在实验二中,在写要函数时,要明确的用0、1写出迷宫的整个布局,这样函数才会输出相应的位置;如果是直接复制ppt上的代码,会出现很多错误,需要去掉一些空格,修改格式。
实验需要改进的地方:
1.在解决算法设计过程中出现的难题之后,程序初步完成,但并不是到此为止,如何改进算法,如何提高算法的时间复杂度、空间复杂度,如何处理一些意想不到的错误和特有情况。
2.在编程过程中,为了增加程序的实用性,将程序适用范围扩大到了实数型,并增加了连续输入功能;
3.在编程过程中,为了增加程序的健壮性,在运算除法时,考虑到除数为“0”时的报错和及时退出;
4.在调试过程中,最初一下子出来程序就出错,为了方便检查错误,故在主函数中增加了检查后缀表达式是否转换正确的函数,并在每一步计算都跟踪结果是否正确;
5.开始写的时候经常忘记写主函数而去调试。并且由于其中的调用函数太多的原因。好多错误出现在括号问题上。并且由于调用函数多的原因常常不知将一个程序从哪里入手去写。还有就是在写主函数时经常忘了定义MaxSize。从而出现错误。
相关文章推荐
- HTML中的figure和gigcaption标签
- 无符号整形压缩与解压缩的一种实现
- 【郑轻】[1799]wrz的压岁钱
- Bootstrap实现自定义进度条
- 同步结构怎么不丢数据?
- 同步结构怎么不丢数据?
- Bubble Cup 8 finals I. Robots protection (575I)
- ListView控件:(3)BaseAdapter适配器生成
- 判断完数、输出完数---C++
- Theano Logistic Regression
- jsonp教程及实现
- 用栈和队列求解迷宫问题
- 各手机截屏方法收集
- RedirectToAction、EmptyResult
- iOs真机调试时编译问题
- 爬虫抓取网页
- 【郑轻】[1804]ZY学长的密码
- ruby on rails 禁止转义 HTML
- Hibernate配置文件的hibernate.hbm2ddl.auto
- eclipse常用设置