表达式树及其变体,以及我是如何借着个原理实现简易计算器的功能的
2014-12-11 18:46
811 查看
本题来源:《算法竞赛入门》第11章11.11.2
本题给的解法:
核心代码:
我为了让这个代码对我更加友好写,对这个代码做了一下修改,改完之后的完整代码是这样的:
改完之后我为了实现这个代码的完整功能,借着个算法提出了个目标:输入一个数学表达式,输出答案。然后对上面的核心代码进行修改,添加我需要的计算功能,删除我不需要的储存功能,就写出了下面的完整程序:
这样一个完整的,具备初级加减乘除功能的计算器程序就实现了。
然后我发现,这个算法和我之前写过的一个有相似之处。Complicated Expression。这个代码可以用这个算法来替换。
本题给的解法:
核心代码:
int build_tree(string exp,int l,int r) { cout<<"l="<<l<<"\tr="<<r<<endl; int c1,c2,p,u; c1=-1; c2=-1; p=0; if(r-l<=1) { u=++cnt; chl[u]=chr[u]=0; operation[u]=exp[x]; return -1; } for(int i=l;i<r;++i) { switch(exp[i]) { case '(':++p;break; case ')':--p;break; case '+': case '-': if(!p)c1=i;break; case '*': case '/': if(!p)c2=i;break; } } if(c1<0) c1=c2; if(c1<0) return build_tree(exp,l+1,r-1); u=++cnt; chl[u]=build_tree(exp,l,c1); chr[u]=build_tree(exp,c1+1,r); operation[u]=exp[c1]; return u; }
我为了让这个代码对我更加友好写,对这个代码做了一下修改,改完之后的完整代码是这样的:
#include<iostream> #include<fstream> #include<string> #include<cstring> using namespace std; ifstream fin("ExpressionTree.in"); #define MAXSIZE 100 string exp; int chl[MAXSIZE],chr[MAXSIZE]; char operation[MAXSIZE]; int cnt=0; int build_tree(string exp,int l,int r) { cout<<"l="<<l<<"\tr="<<r<<endl; int c1,c2,p,u; c1=-1; c2=-1; p=0; if(r-l<=1) { u=++cnt; chl[u]=chr[u]=-1; operation[u]='#'; return -1; } for(int i=l;i<r;++i) { switch(exp[i]) { case '(':++p;break; case ')':--p;break; case '+': case '-': if(!p)c1=i;break; case '*': case '/': if(!p)c2=i;break; } } if(c1<0) c1=c2; if(c1<0) return build_tree(exp,l+1,r-1); u=++cnt; chl[u]=build_tree(exp,l,c1); chr[u]=build_tree(exp,c1+1,r); operation[u]=exp[c1]; return u; } int main() { memset(operation,0,sizeof(operation)); memset(chl,0,sizeof(operation)); memset(chr,0,sizeof(operation)); fin>>exp; build_tree(exp,0,exp.size()); for(int i=1;i<=cnt;++i) cout<<operation[i]<<"\t"; cout<<endl; return 0; }
改完之后我为了实现这个代码的完整功能,借着个算法提出了个目标:输入一个数学表达式,输出答案。然后对上面的核心代码进行修改,添加我需要的计算功能,删除我不需要的储存功能,就写出了下面的完整程序:
#include<iostream> #include<fstream> #include<string> #include<cstring> using namespace std; ifstream fin("../Data/CalExp.in"); #define MIN -32767 string str; int result; int checkVadality(int val,int l,int r) { if(val==MIN) { val=0; for(int i=l;i<r;++i) if(str[i]>='0'&&str[i]<='9') val=val*10+(str[i]-'0'); } return val; } int calc(string s,int l,int r) { int c1=-1,c2=-1,p=0; int s1=0,s2=0; if(r-l<=1) { return MIN; } for(int i=l;i<r;++i) { switch(s[i]) { case '(':++p;break; case ')':--p;break; case '+': case '-':if(!p)c1=i;break; case '*': case '/':if(!p)c2=i;break; } } if(c1<0) c1=c2; if(c1<0) { return calc(s,l+1,r-1); } s1=calc(s,l,c1); s2=calc(s,c1+1,r); s1=checkVadality(s1,l,c1); s2=checkVadality(s2,c1+1,r); if(s[c1]=='+') { return s1+s2; } else if(s[c1]=='-') { return s1-s2; } else if(s[c1]=='*') { return s1*s2; } else if(s[c1]=='/') { return s1/s2; } } int main() { while(cin>>str) cout<<calc(str,0,str.size()); return 0; }
这样一个完整的,具备初级加减乘除功能的计算器程序就实现了。
然后我发现,这个算法和我之前写过的一个有相似之处。Complicated Expression。这个代码可以用这个算法来替换。
相关文章推荐
- 傅立叶变换的原理、意义以及如何用Matlab实现快速傅立叶变换
- 如何写出正确的二分查找?——利用循环不变式理解二分查找及其变体的正确性以及构造方式
- Jsp中如何使用Ckeditor富文本编译器以及实现上传文件的功能
- 前端分页功能的实现以及原理
- VB的ShowInTaskbar功能分析以及用VC的实现 如何隐藏对话框在工具栏上的按钮
- [Android开发] 在项目中快速实现 列表字母排序滑动索引 功能原理以及过程代码
- 前端分页功能的实现以及原理
- Android 中免 Root 实现 Hook 的 Dexposed 实现原理解析以及如何实现应用的热修复
- 前端分页功能的实现以及原理
- 加强2注解。泛型。类加载器及其委托机制。代理的概念与作用原理,AOP概念。实现AOP功能的封装与配置。类似Spring。
- CMAP原理及其在MFC中的实现(MAP模板没有顺序遍历的功能)
- C# listview如何显示网格线以及如何实现item的选中功能
- 如何写出正确的二分查找?——利用循环不变式理解二分查找及其变体的正确性以及构造方式
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复
- 如何写出正确的二分查找?——利用循环不变式理解二分查找及其变体的正确性以及构造方式
- C语言中strtok使用方法与原理,以及自实现函数功能
- 如何在App中实现朋友圈功能之一朋友圈实现原理浅析——箭扣科技Arrownock
- 前端分页功能的实现以及原理
- 类似于花瓣、发现啦的 Chrome 的插件截图功能是如何实现的?具体的实现原理是什么?
- Android中免Root实现Hook的Dexposed框架实现原理解析以及如何实现应用的热修复