逆波兰表达式的生成及计算
来源:互联网 发布:淘宝介入处理流程 编辑:程序博客网 时间:2024/06/07 09:02
逆波兰表达式(后缀表达式)生成算法:
(1)构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示法表示的简单算术表达式,为方便起见,认为地在字符串后面加入一个特殊字符“;”,并设其优先级为0。
(3)从左至右扫描该算术表达式的每一个字符,如果该字符是数字,则分析到该数字串的结束并将该数字串加入结果字符串,小数点亦算入数字串。
(4)如果该字符是运算符,则按如下操作:
如果该字符是左括号“(”,则该字符直接压入运算符栈。
如果该字符是右括号“)”,则把运算符栈顶元素弹出直至第一次遇到左括号。
如果该字符是算术运算符且其优先关系高于运算符栈顶的运算符,则将该运算符入栈。
否则,将栈顶的运算符从栈中弹出至结果字符串末尾,直至栈顶运算符的优先级低于当前运算符,并将该字符入栈。
(5)重复上述操作(3)-(4)直至扫描完整个简单算术表达式(遇到特殊字符“;”)。
如:
一般简单表达式:((4+5)*6-5)/2+3*2
逆波兰表达式:4 5 + 6 * 5 - 2 / 3 2 * +
步骤如下:
运算符栈 结果字符串
第1步: ; ""
第2步: ;( ""
第3步: ;(( ""
第4步: ;(( "4"
第5步: ;((+ "4 5"
第6步: ;( "4 5 +"
第7步: ;(* "4 5 +"
第8步: ;(* "4 5 + 6"
第9步: ;(- "4 5 + 6 *"
第10步: ;(- "4 5 + 6 * 5"
第11步: ; "4 5 + 6 * 5 -"
第12步: ;/ "4 5 + 6 * 5 -"
第13步: ;/ "4 5 + 6 * 5 - 2"
第14步: ;+ "4 5 + 6 * 5 - 2 /"
第15步: ;+ "4 5 + 6 * 5 - 2 / 3"
第16步: ;+* "4 5 + 6 * 5 - 2 / 3"
第17步: ;+* "4 5 + 6 * 5 - 2 / 3 2"
第18步: ;+ "4 5 + 6 * 5 - 2 / 3 2 *"
第19步: ; "4 5 + 6 * 5 - 2 / 3 2 * +"
其中运算符优先级如下:
* / :2
+ - :1
; :0
逆波兰表达式求值算法:
(1)构建一个操作数栈,类型为float;
(2)依次扫描逆波兰表达式的每一项;
(3)如果是数字串则压入操作数栈;
(4)如果是运算符,则从操作数栈顶弹出两个操作数,与运算符进行运算,结果压入操作数栈。(计算减法和除法时需要注意数字的先后)
(5)不断重复以上步骤直至扫描完逆波兰表达式。
(6)此时操作数栈必定只剩一个数据,即为逆波兰表达式的值,弹出输出。
如:如上表达式计算结果为:30.5
(1)构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。
(2)读入一个用中缀表示法表示的简单算术表达式,为方便起见,认为地在字符串后面加入一个特殊字符“;”,并设其优先级为0。
(3)从左至右扫描该算术表达式的每一个字符,如果该字符是数字,则分析到该数字串的结束并将该数字串加入结果字符串,小数点亦算入数字串。
(4)如果该字符是运算符,则按如下操作:
如果该字符是左括号“(”,则该字符直接压入运算符栈。
如果该字符是右括号“)”,则把运算符栈顶元素弹出直至第一次遇到左括号。
如果该字符是算术运算符且其优先关系高于运算符栈顶的运算符,则将该运算符入栈。
否则,将栈顶的运算符从栈中弹出至结果字符串末尾,直至栈顶运算符的优先级低于当前运算符,并将该字符入栈。
(5)重复上述操作(3)-(4)直至扫描完整个简单算术表达式(遇到特殊字符“;”)。
如:
一般简单表达式:((4+5)*6-5)/2+3*2
逆波兰表达式:4 5 + 6 * 5 - 2 / 3 2 * +
步骤如下:
运算符栈 结果字符串
第1步: ; ""
第2步: ;( ""
第3步: ;(( ""
第4步: ;(( "4"
第5步: ;((+ "4 5"
第6步: ;( "4 5 +"
第7步: ;(* "4 5 +"
第8步: ;(* "4 5 + 6"
第9步: ;(- "4 5 + 6 *"
第10步: ;(- "4 5 + 6 * 5"
第11步: ; "4 5 + 6 * 5 -"
第12步: ;/ "4 5 + 6 * 5 -"
第13步: ;/ "4 5 + 6 * 5 - 2"
第14步: ;+ "4 5 + 6 * 5 - 2 /"
第15步: ;+ "4 5 + 6 * 5 - 2 / 3"
第16步: ;+* "4 5 + 6 * 5 - 2 / 3"
第17步: ;+* "4 5 + 6 * 5 - 2 / 3 2"
第18步: ;+ "4 5 + 6 * 5 - 2 / 3 2 *"
第19步: ; "4 5 + 6 * 5 - 2 / 3 2 * +"
其中运算符优先级如下:
* / :2
+ - :1
; :0
逆波兰表达式求值算法:
(1)构建一个操作数栈,类型为float;
(2)依次扫描逆波兰表达式的每一项;
(3)如果是数字串则压入操作数栈;
(4)如果是运算符,则从操作数栈顶弹出两个操作数,与运算符进行运算,结果压入操作数栈。(计算减法和除法时需要注意数字的先后)
(5)不断重复以上步骤直至扫描完逆波兰表达式。
(6)此时操作数栈必定只剩一个数据,即为逆波兰表达式的值,弹出输出。
如:如上表达式计算结果为:30.5
逆波兰表达式生成及求值的C++实现:
#include<stdio.h> #include<math.h> #include<iostream>#include<stack>#include<map>#include<string.h>#include<string>#include<stdlib.h>#include<sstream>using namespace std;typedef struct{string s;int type; //0:operatorChar;1:number}expNode;float calPoland(stack<expNode> t);int operatorPriority(char c){switch(c){case '#':return 1;case '+':case '-':return 2;case '*':case '/':return 3;default:return 1;}}float calculate(float a,float b,char c){switch(c){case '+':return a+b;case '-':return a-b;case '*':return a*b;case '/':return a/b;default:; }}stack<expNode> makePoland(string t){int len=t.length(),i; char c;stack<expNode> expStack;stack<char> charStack;charStack.push('#');for(i=0;i<len;i++){c=t[i]; if(c=='(') { charStack.push(c);}else if(c==')'){while(1){c=charStack.top();charStack.pop();if(c=='(')break;expNode node;node.s.append(1,c);node.type=0;expStack.push(node);}}else if(c>='0'&&c<='9'){expNode node;node.s.append(1,c);node.type=1;while(1){if(t[i+1]>='0'&&t[i+1]<='9'&&i<len){node.s.append(1,t[i+1]);i++;}else break;} expStack.push(node);}else if(operatorPriority(c)>operatorPriority(charStack.top())) {charStack.push(c);}else if(operatorPriority(c)<=operatorPriority(charStack.top())) {while(1){char topc=charStack.top();if(operatorPriority(c)>operatorPriority(topc)){charStack.push(c);break;}expNode node;node.s.append(1,topc);node.type=0;expStack.push(node);charStack.pop();}}printf("%d :",i);stack<expNode> x=expStack;while(!x.empty()){expNode node=x.top();cout<<node.s<<' ';x.pop();} printf("\n");}while(!charStack.empty()){c=charStack.top();charStack.pop();if(c=='#')break;expNode node;node.s.append(1,c);node.type=0;expStack.push(node);}stack<expNode> x=expStack;while(!expStack.empty())expStack.pop();while(!x.empty()){expNode node=x.top();x.pop();expStack.push(node);} /*while(!expStack.empty()){expNode node=expStack.top();cout<<node.s;expStack.pop();} printf("\n"); *///printf("%f\n",calPoland(expStack));return expStack; }float calPoland(stack<expNode> t){stack<float> numStack;int x=t.size();while(!t.empty()){expNode node=t.top();t.pop();if(node.type==1){float num;istringstream iss(node.s);iss>>num;numStack.push(num);}else if(node.type==0){float a=numStack.top();numStack.pop();float b=numStack.top();numStack.pop();char c=node.s[0];float ans=calculate(b,a,c);numStack.push(ans);}else {printf("error:expStack type error!\n");}}float ans=numStack.top();return ans;}int main(){//string s="((44+55)*66-5)/22+3*2" ;string s="((4+5)*6-5)/2+3*2" ;stack<expNode> expStack=makePoland(s);float ans=calPoland(expStack);printf("%f\n",ans);}
0 0
- 逆波兰表达式的生成及计算
- 逆波兰表达式的生成及计算
- 逆波兰表达式的产生及计算
- 逆波兰表达式的生成
- 逆波兰表达式计算
- 生成逆波兰表达式
- 逆波兰表达式的计算问题
- 续前篇-关于逆波兰表达式的计算
- 计算表达式-逆波兰表达式
- 逆波兰表达式的生成(Java版)
- 递归计算逆波兰表达式
- Java解析字符串表达式--逆波兰表达式的计算
- android 逆波兰表达式的应用(二)逆波兰表达式的计算 -----小达
- android逆波兰表达式的应用(四)逆波兰表达式的计算实现 -----小达
- Java解析字符串表达式--逆波兰表达式的生成
- 数据结构-------计算逆波兰表达式(后缀表达式)
- 计算表达式的值c++逆波兰式实现方法
- 中缀表达式到逆波兰表达式的转换及求值
- LVM管理体系(三)通过扩展VG扩展逻辑卷(操作步骤)
- OpenGL读取PLY模型文件并绘制 Read and draw ply model by OpenGL
- IOS开发之──传感器使用
- linux命令行学习
- 高速数据采集存储回放系统—全球顶级超宽带高速数据采集存储回放系统6000MB/S!
- 逆波兰表达式的生成及计算
- arcgis10.2 SDE (sqlserver)安装及使用
- python socket Select模型
- [codility]NailingPlanks
- hdu 1022 Train Problem I 栈模拟
- BlueZ移植——ARM9
- Python3.2官方文档教程--深入模块
- 暴库漏洞
- LVM管理体系(四)缩小逻辑卷(操作步骤)