逆波兰表达式
2015-09-01 16:46
337 查看
逆波兰表达式又叫做后缀表达式。它的语法规定,表达式必须以逆波兰表达式的方式给出。
正常的表达式 逆波兰表达式
a+b ---> a,b,+
a+(b-c) ---> a,b,c,-,+
a+(b-c)*d ---> a,b,c,-,d,*,+
a+d*(b-c)--->a,d,b,c,-,*,+
a=1+3 ---> a=1,3 +
(1-2)*(3+6)---> 1,2,-,3,6,+,*
利用栈的知识,可以将逆波兰表达式的值求出。
![](http://img.blog.csdn.net/20150901164156954?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
代码:目前只能计算0-9以内的包含括号的加减乘除,十几二十甚至浮点数的计算有待进一步开发
主要问题是:一个字符串存储逆波兰表达式,包含数字,和字符,很难统一到一起。还有数据长度的问题,目前的代码统一是1位,这样最容易实现。
正常的表达式 逆波兰表达式
a+b ---> a,b,+
a+(b-c) ---> a,b,c,-,+
a+(b-c)*d ---> a,b,c,-,d,*,+
a+d*(b-c)--->a,d,b,c,-,*,+
a=1+3 ---> a=1,3 +
(1-2)*(3+6)---> 1,2,-,3,6,+,*
利用栈的知识,可以将逆波兰表达式的值求出。
代码:目前只能计算0-9以内的包含括号的加减乘除,十几二十甚至浮点数的计算有待进一步开发
主要问题是:一个字符串存储逆波兰表达式,包含数字,和字符,很难统一到一起。还有数据长度的问题,目前的代码统一是1位,这样最容易实现。
#include <iostream> #include <string> #include <stack> using namespace std; #define maxsize 100 // 获取操作符的优先级 int precedence(char op) { switch(op) { case '^': return 3; case '*': case '/': case '%': return 2; case '+': case '-': return 1; case '(': return 0; } } //判断是否是操作符 int IsOperator(char ch) { switch(ch) { case '^': case '*': case '/': case '%': case '+': case '-': return 1; default: return 0; } } // 转换 void exchange(char *pSource, char *pDest) { char oper[maxsize]; // 定义操作符栈 int top = -1; // 初始化栈定位置 char ch; if(pSource==NULL || pDest==NULL) return; oper[++top] = '('; // ‘(' 初始化栈 while((ch = *pSource++) != '#') { if(ch == '(') // '(' 直接入栈 { oper[++top] = ch; } else if(ch == ')') // 运算符出栈拷入目标数组,直到'(' { while(oper[top] != '(') { *pDest++ = oper[top--]; } top--; } else if(IsOperator(ch)) { if(precedence(ch) > precedence(oper[top])) // 优先级大与栈顶字符,直接入栈 { oper[++top] = ch; } else // 优先级小与栈顶字符,所有优先级大的字符拷入目标数组,再入栈 { while(precedence(oper[top]) >= precedence(ch)) { *pDest++ = oper[top--]; } oper[++top] = ch; } } else // 不是运算符直接拷入目标数组 { *pDest++ = ch; } } while(top != 0) // 源数组遍历完毕,栈中操作符拷入目标数组 { *pDest++ = oper[top--]; } *pDest = '#'; } int calculate(char *c,int len)//根据逆波兰表达式,求解值 { stack<int> s;//声明一个栈 int i=0; int p; int m=0,n=0; while(i<len) { if(c[i]=='+'||c[i]=='-'||c[i]=='*'||c[i]=='/') { m=s.top(); s.pop(); n=s.top(); s.pop(); if(c[i]=='+') { s.push(m+n); } if(c[i]=='-') { s.push(n-m); } if(c[i]=='*') { s.push(m*n); } if(c[i]=='/') { s.push(n/m); } } else { p=c[i]-'0'; s.push(p); } i++; } if(s.size()!=1) { cout<<"表达式错误"<<endl; return 0; } return s.top(); } int main() { string s; getline(cin,s); char X[maxsize]; int i=0; int len=s.length(); for(i=0;i<len;i++) { X[i]=s[i]; } X[i]='#'; //"3*2^(4+2*2-1*3)-5#"; char B[maxsize]; exchange(X, B); for(i=0; B[i]!='#'; i++) { cout<<B[i]; } cout<<endl; //以上是给了例子求逆波兰表达式,比如(1-2)*(4+5)输出 12-45+* //以下是根据逆波兰表达式求值 int lenb=i; cout<<calculate(B,lenb)<<endl; return 0; }
相关文章推荐
- HDU2108 Shape of HDU
- codeforces 415E E. Devu and Flowers(组合数学+容斥原理)
- SharePoint Server 2013介绍v2
- 用一个bat方法 快速进入mysql的cmd
- PAT 1075. PAT Judge (25)
- park入门实战系列--6.SparkSQL(下)--Spark实战应用
- #include<list>
- Android笔记(十三)AsyncTask(一)
- mac os x 添加自定义字体库
- handlebars-----另一种help的写法
- 萤石A1互联网报警盒子破解细节分析
- web.xml中的url-pattern映射规则
- 关于squirrel的那些事
- Compress--- The input point cloud
- 浅谈深度学习(Deep Learning)的基本思想和方法
- hdu 2899 Strange fuction 三分
- Ext错误"Uncaught SyntaxError: Unexpected token <"
- 提高mysql的写入效率
- 大话设计模式笔记 策略模式
- 问题:oracle CLOB类型;结果:oracle中Blob和Clob类型的区别