博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
表达式求值、表达式转二叉树
阅读量:6517 次
发布时间:2019-06-24

本文共 4773 字,大约阅读时间需要 15 分钟。

1、后序表达式求值:

后续表达式(逆波兰式)的特点:没有括号。

求值方法:

从前向后扫,

遇到操作数压栈;

遇到操作符,从栈中取出2个操作数运算,结果压栈。

最终栈中所剩的数为结果。

2、中序表达式求值

我们先来定义运算符的优先级:
(
+,-
*,/,%
从上到下依次升高
准备2个栈,一个专门存放运算符,另一个专门存放操作数。
1.遇到),那么退栈计算到(为止.结果压栈。
2.遇到运算数.那么压栈。
3.如果当前运算符优先级低于栈顶运算符.那么计算栈顶运算符并将结果压栈.
4.否则压栈.

计算带括号和浮点数的表达式:

View Code
#include
#include
#include
#include
using namespace std; typedef string::size_type it; char Compare(char op,char ch) //优先级比较 { if((op=='#'&&ch=='#')||(op=='('&&ch==')')) return '='; if(ch=='#') return '<'; if(op=='#') return '>'; if(op=='(') return '>'; if(ch==')') return '<'; if(ch=='(') return '>'; if(ch=='*'||ch=='/') if(op=='+'||op=='-') return '>'; else return '<'; if(ch=='+'||ch=='-') return '<'; } void modify(string& s) //优化表达式 { string s1="()+-*/"; for(it i=0;i
ch; bool valid=true; for(it i=0;i
& num,stack
& ops,const string & s) { string s1="()+-*/#"; it i=0; while(i
') ops.push(ch); else if(Compare(op,ch)=='=') ops.pop(); else { while(1) { char c=ops.top(); if(Compare(c,ch)=='>') { ops.push(ch); break; } else if(Compare(c,ch)=='=') { ops.pop(); break; } else { char optr=ops.top(); ops.pop(); double n1=num.top(); num.pop(); double n2=num.top(); num.pop(); double value; if(optr=='+') value=n2+n1; if(optr=='-') value=n2-n1; if(optr=='*') value=n2*n1; if(optr=='/') { double E=0.00001; if( n1>-E && n1
num; stack
ops; ops.push('#'); string s; cout<<"Input the string:"<

将中序表达式转换成后序表达式(逆波兰表达式)的算法:

(1)初始化一个空的运算符栈
(2)在没有到达中缀表达式的结尾及没有发生错误的时候,执行以下步骤:
 1.获取表达式中的一个标记(常数、变量、算术运算符,左括号,右括号)。
 2.如果标记是:
   i.  一个左括号,将其压入栈中
   ii. 一个右括号,连续弹出并显示栈中的元素,直到遇到一个左括号,不要显示这个左括号。(如果直到栈为空还没遇到一个左括号,则是一个错误)
   iii.一个运算符,如果栈为空,或者标记具有比栈顶元素更高的优先级,则将其压入栈中。否则出并显示栈顶的元素,接着继续比较标记和新的栈顶元素。(运算符比左括号的优先级高)
   iv 一个操作数,显示它
(3)当到达中缀表达式的结尾时,弹出并显示栈中的元素直到栈为空为止。

参考代码:

View Code
//将表达式转化为逆波兰表达式   string RPN(const string& exp)   {        char token,toptoken;        stack
oper; string RPNexp; int length=exp.length(); for(int i=0;i
num; int num1,num2,value; int length=exp.length(); for(int i=0;i

字符串表达式转化为二叉树:

View Code
//表达式转二叉树的源代码   #include
#include
#include
using namespace std; class Node { public: char oper;//操作数或运算符 Node *left;//左子树 Node *right;//右子树 Node():left(NULL),right(NULL),oper(0){} Node(char op):left(NULL),right(NULL),oper(op){} }; //判断是否为运算符 bool isOper(char op) { char oper[]={
'(',')','+','-','*','/'}; for(int i=0;i
left != NULL) freeTree(p->left); if(p->right != NULL) freeTree(p->right); delete(p); } //递归先序遍历 void preOrderTraverse(Node *p) { if(p!=NULL) { cout<
oper; preOrderTraverse(p->left); preOrderTraverse(p->right); } } //中序遍历 void inOrderTraverse(Node *p) { if(p) { if(p->left) { if(isOper(p->left->oper)&&getOperPri(p->left->oper)
oper)) { cout<<"("; inOrderTraverse(p->left); cout<<")"; } else inOrderTraverse(p->left); } cout<
oper; if(p->right) { if(isOper(p->right->oper)&&getOperPri(p->right->oper)<=getOperPri(p->oper)) { cout<<"("; inOrderTraverse(p->right); cout<<")"; } else inOrderTraverse(p->right); } } } //表达式生成二叉树 void generateTree(Node*& p, string expr) { stack
operStack; stack
dataStack; char tmpchr,c; int idx=0; tmpchr=expr[idx++]; while(operStack.size()!=0 || tmpchr!='\0') { if(tmpchr!='\0' && !isOper(tmpchr))//不是运算符,则进操作数的栈 { p=new Node(tmpchr); dataStack.push(p); tmpchr=expr[idx++]; } else { switch(tmpchr) { case '('://进栈 operStack.push('('); tmpchr=expr[idx++]; break; case ')'://脱括号 while(true) { c=operStack.top(); operStack.pop(); if(c=='(') { break; } p=new Node(c); if(dataStack.size()) { p->right=dataStack.top(); dataStack.pop(); } if(dataStack.size()) { p->left=dataStack.top(); dataStack.pop(); } dataStack.push(p); } tmpchr=expr[idx++]; break; default: if(operStack.size()==0 || tmpchr!='\0' && getOperPri(operStack.top())< getOperPri(tmpchr)) { //进栈 operStack.push(tmpchr); tmpchr=expr[idx++]; } else { //出栈 p=new Node(operStack.top()); p->oper=operStack.top(); if(dataStack.size()) { p->right=dataStack.top(); dataStack.pop(); } if(dataStack.size()) { p->left=dataStack.top(); dataStack.pop(); } dataStack.push(p); operStack.pop(); } break; } } } p=dataStack.top(); dataStack.pop(); } int main() { string expression; Node* tree; cout<<"请输入字符串表达式:"; cin>>expression; generateTree(tree,expression); cout<<"前缀表达式为:"; preOrderTraverse(tree); cout<

 

转载地址:http://itofo.baihongyu.com/

你可能感兴趣的文章
应用程序框架实战三十四:数据传输对象(DTO)介绍及各类型实体比较(转)
查看>>
放量滞涨,抛出信号
查看>>
BeanFactory not initialized or already closed - call 'refresh' before accessing beans解决办法
查看>>
dSYM 文件分析工具
查看>>
R语言合并data.frame
查看>>
linux主机下的Vmware Workstation配置NAT设置 端口映射-Ubuntu为例
查看>>
unity physics joint
查看>>
TD的访问地址
查看>>
JAVA常见面试题之Forward和Redirect的区别
查看>>
tmpFile.renameTo(classFile) failed 错误
查看>>
【甘道夫】Apache Hadoop 2.5.0-cdh5.2.0 HDFS Quotas 配额控制
查看>>
一张图看懂normal,static,sealed,abstract 的 区别
查看>>
Task的使用
查看>>
grep和正则表达式
查看>>
s:iterator巧妙控制跳出循环
查看>>
移动互联网思维
查看>>
redis-手写redis切片和非切片连接池并注入springboot中
查看>>
Serv-U 的升级及数据备份和迁移【转】
查看>>
webstorm无法显示左边文件夹目录的解决方法
查看>>
Android数据保存之文件保存
查看>>