CSUFT 编译原理实验三 中缀表达式转逆波兰表达式求值
2016-06-23 12:48
369 查看
下面代码是完整版的 加入了单目减运算(即'-'负号 代码中用@符号代替)、浮点数运算、乘方运算。
要用自己写的模板化代码可以参考下面链接 http://blog.csdn.net/geekcoder/article/details/6829386
View Code
要用自己写的模板化代码可以参考下面链接 http://blog.csdn.net/geekcoder/article/details/6829386
#include <iostream> #include <cstdio> #include <stack> #include <cmath> using namespace std; bool isOperator(char op) { switch(op) { case '+': case '-': case '*': case '/': case '^': case '@': return 1; default : return 0; } } int priority(char op) { switch(op) { case '#': return -1; case '(': return 0; case '+': case '-': return 1; case '*': case '/': return 2; case '^': return 3; case '@': return 4; default : return -1; } } // 把中缀表达式转换为后缀表达式,返回后缀表达式的长度(包括空格) void postfix(char pre[] ,char post[],int &n) { int i = 0 ,j=0; stack<char>st; // 初始化存储操作符的栈 st.push('#'); // 首先把结束标志‘#’放入栈底 while(pre[i]!='#') { if((pre[i]>='0' && pre[i] <='9')||pre[i] =='.') // 遇到数字和小数点直接写入后缀表达式 { post[j++] = pre[i]; n++; } else if (pre[i]=='(') // 遇到“(”不用比较直接入栈 st.push(pre[i]); else if(pre[i] ==')') // 遇到右括号将其对应左括号后的操作符(操作符栈中的)全部写入后缀表达式 { while(st.top()!='(') { char t = st.top(); st.pop(); post[j++] = t; n++; } st.pop(); // 将“(”出栈,后缀表达式中不含小括号 } else if (isOperator(pre[i])) { post[j++] = ' '; // 用空格分开操作数( n++; while(priority(pre[i]) <= priority(st.top())) { // 当前的操作符小于等于栈顶操作符的优先级时,将栈顶操作符写入到后缀表达式,重复此过程 char t = st.top(); st.pop(); post[j++] = t; n++; } st.push(pre[i]); // 当前操作符优先级大于栈顶操作符的优先级,将该操作符入栈 } i++; } while(!st.empty()) // 将所有的操作符加入后缀表达式 { post[j++] = st.top(); st.pop(); n++; } } double read(char str[],int *i) { double x=0.0; int k = 0; while(str[*i] >='0' && str[*i]<='9') // 处理整数部分 { x = x*10+(str[*i]-'0'); (*i)++; } if(str[*i]=='.') // 处理小数部分 { (*i)++; while(str[*i] >= '0'&&str[*i] <='9') { x = x * 10 + (str[*i]-'0'); (*i)++; k++; } } while(k!=0) { x /= 10.0; k--; } return x; } double postfix_value(char post[]) { stack<double>st; // 操作数栈 int i=0 ; double x1,x2; while(post[i] !='#') { if(post[i] >='0' && post[i] <='9') st.push(read(post,&i)); else if(post[i] == ' ') i++; else if (post[i] =='+') { x2 = st.top(); st.pop(); x1 = st.top(); st.pop(); st.push(x1+x2); i++; } else if (post[i] =='-') { x2 = st.top(); st.pop(); x1 = st.top(); st.pop(); st.push(x1-x2); i++; } else if (post[i] =='*') { x2 = st.top(); st.pop(); x1 = st.top(); st.pop(); st.push(x1*x2); i++; } else if (post[i] =='/') { x2 = st.top(); st.pop(); x1 = st.top(); st.pop(); st.push(x1/x2); i++; } else if (post[i] =='^') //乘方运算符 { x2 = st.top(); st.pop(); x1 = st.top(); st.pop(); double t = pow(x1,x2); st.push(t); i++; } else if (post[i] =='@') //单目-运算符用@代替 { x2 = st.top(); st.pop(); x2 = 0-x2; st.push(x2); i++; } } return st.top(); } int main() { stack<int>st ; char exp[100]; cout << "输入表达式(中缀,以#结束):"; cin >> exp; char post[100] ; int n =0; // 返回后缀表达式的长度 postfix(exp,post,n); cout <<"逆波兰表达式为:"; for( int i =0 ;i < n ;i++) cout << post[i] ; cout << "\n由逆波兰表达式计算出的数值结果: "; cout << postfix_value(post) << endl; return 0; }
View Code
相关文章推荐
- Java使用socket接收http请求,read方法阻塞的问题
- sdut 2506 完美网络
- 在opencv中显示无边框的窗口
- java “错误:编码GBK 的不可映射字符”解决方法
- Android 6.0 运行时权限处理
- 前端页面动态获取后台执行sql的执行条数(超实用)
- 再也不必当心我的密码了,多个SAP 客户端自动输入密码
- js控件设置背景色
- sqlserver中复合索引和include索引到底有多大区别?
- Android之SurfaceView学习(一)
- 【leetcode】121. Best Time to Buy and Sell Stock
- 【UWP开源】图片编辑器,带贴图、滤镜、涂鸦等功能
- fedora 24 使用扇贝网页版没有声音
- android ListView 重新进入后如何回到之前位置
- 安装Docker和下载images镜像和常用Docker命令
- Top K Frequent Elements
- sass学习--基本特性(基础篇)
- android shape 和 select 的使用
- 用户体验
- Linux 如何实现 VLAN - 每天5分钟玩转 OpenStack(12)