表达式计算算法总结
来源:互联网 发布:ui和程序员漫画 编辑:程序博客网 时间:2024/04/30 15:56
表达式计算算法总结
电子科技大学软件学院03级2班 周银辉
转载请注明出处
一,使用双栈
一个操作数栈optr,一个操作符栈opnd.
思想是:置操作数栈为空,操作符栈压入元素"#"(它具有最高优先级),依次读入表达式中的每个字
符w
if(w为操作数)
{
optr.push(w);
}
else
{
switch(w与操作符栈顶元素进行优先级比较)
{
case >:
opnd.push(w);
break;
case <:
op=optr.pop();
a=opnd.pop();
b=opnd.pop();
c=计算(a op b);
opnd.push(c);
break;
case ==:
oper.pop();
break;
}
}
重复上述操作直到表达式处理完毕。
最后操作数栈剩余的操作数就是计算的最终结果。
二,使用二叉树。
流程:将表达式(中缀)转化为二叉树,后序遍历该二叉树得到表达式的逆波兰表达式(后缀),计算
该逆波兰表达式
其中将中缀表达式转化为二叉树的算法是:
设表达式类Express,树类Tree, 由MakeNode(value)来生成值为value左右孩子为空的节点
void M(Express exp, Tree t)
{
if(exp为数或简单变量)
{
t = MakeNode(exp);
}
else if(exp 形如"ex1 op ex2")//即op为二元操作符
{
t = MakeNode(op);
M(ex1, t.LeftChild);
M(ex2, t.RightChild);
}
else if( exp 形如"ex1 op")//比如5!
{
t = MakeNode(op);
M(ex1, t.RightChild);
}
}
后序遍历二叉树的算法是:
void F(Tree t)
{
if(t==null)
{
return;
}
F(t.LeftChild);
F(t.RightChild);
visit(t);//访问t
}
计算逆波兰表达式的算法:
设表达式记号tkn;操作数栈stk;
while( (tkn=GetNextToken()) != null)
{
if(tkn == 操作数)
{
stk.push(tkn);
continue;
}
else if(tkn == 操作符)
{
a=stk.pop();
b=stk.pop();
c= 计算a tkn b;
stk.push(c);
continue;
}
}
最后stk中剩余的操作数就是计算结果。
三,我原创的方法:利用编译器
我们对表达式的计算将摆脱传统的观点(即传统的对表达式进行词法分析,语法分析等等),在编
写我们的计算器的代码中,不会有任何的词法分析、语法分析、后缀表达式转换等等。
启发来自于这里:
假设有一个函数F
double F()
{
double r = 3*4.5+sin(50);
return r;
}
那么,我们就可以 Console.WriteLine("{0}",F());
我们计算了3*4.5+sin(50),但我们有进行麻烦的词法分析与语法分析吗?没有,谁帮我们做了,
编译器,ok,关键就在这:如果计算器用户在计算器主窗口上输入表达式
3*4.5+sin(50),我们负责把它传给F中的r,然后我们再把F的返回值输出到用户界面上就OK了,我们
要做的就这些。
详细的算法可以到我的博客 http://zhouyinhui.cnblogs.com/ 参看“用.net打造可编程的表达式计算器“一文。
电子科技大学软件学院03级2班 周银辉
转载请注明出处
一,使用双栈
一个操作数栈optr,一个操作符栈opnd.
思想是:置操作数栈为空,操作符栈压入元素"#"(它具有最高优先级),依次读入表达式中的每个字
符w
if(w为操作数)
{
optr.push(w);
}
else
{
switch(w与操作符栈顶元素进行优先级比较)
{
case >:
opnd.push(w);
break;
case <:
op=optr.pop();
a=opnd.pop();
b=opnd.pop();
c=计算(a op b);
opnd.push(c);
break;
case ==:
oper.pop();
break;
}
}
重复上述操作直到表达式处理完毕。
最后操作数栈剩余的操作数就是计算的最终结果。
二,使用二叉树。
流程:将表达式(中缀)转化为二叉树,后序遍历该二叉树得到表达式的逆波兰表达式(后缀),计算
该逆波兰表达式
其中将中缀表达式转化为二叉树的算法是:
设表达式类Express,树类Tree, 由MakeNode(value)来生成值为value左右孩子为空的节点
void M(Express exp, Tree t)
{
if(exp为数或简单变量)
{
t = MakeNode(exp);
}
else if(exp 形如"ex1 op ex2")//即op为二元操作符
{
t = MakeNode(op);
M(ex1, t.LeftChild);
M(ex2, t.RightChild);
}
else if( exp 形如"ex1 op")//比如5!
{
t = MakeNode(op);
M(ex1, t.RightChild);
}
}
后序遍历二叉树的算法是:
void F(Tree t)
{
if(t==null)
{
return;
}
F(t.LeftChild);
F(t.RightChild);
visit(t);//访问t
}
计算逆波兰表达式的算法:
设表达式记号tkn;操作数栈stk;
while( (tkn=GetNextToken()) != null)
{
if(tkn == 操作数)
{
stk.push(tkn);
continue;
}
else if(tkn == 操作符)
{
a=stk.pop();
b=stk.pop();
c= 计算a tkn b;
stk.push(c);
continue;
}
}
最后stk中剩余的操作数就是计算结果。
三,我原创的方法:利用编译器
我们对表达式的计算将摆脱传统的观点(即传统的对表达式进行词法分析,语法分析等等),在编
写我们的计算器的代码中,不会有任何的词法分析、语法分析、后缀表达式转换等等。
启发来自于这里:
假设有一个函数F
double F()
{
double r = 3*4.5+sin(50);
return r;
}
那么,我们就可以 Console.WriteLine("{0}",F());
我们计算了3*4.5+sin(50),但我们有进行麻烦的词法分析与语法分析吗?没有,谁帮我们做了,
编译器,ok,关键就在这:如果计算器用户在计算器主窗口上输入表达式
3*4.5+sin(50),我们负责把它传给F中的r,然后我们再把F的返回值输出到用户界面上就OK了,我们
要做的就这些。
详细的算法可以到我的博客 http://zhouyinhui.cnblogs.com/ 参看“用.net打造可编程的表达式计算器“一文。
- 表达式计算算法总结
- 表达式计算算法总结
- 表达式计算算法总结
- 算法训练 表达式计算
- 算法训练 表达式计算
- 算法训练 表达式计算
- 算法训练 表达式计算
- 算法训练 表达式计算
- 算法训练 表达式计算
- 算法训练 表达式计算
- 算法训练 表达式计算
- 算法训练 表达式计算
- 算法训练 表达式计算
- 表达式计算 Java算法
- 算法训练 表达式计算
- java数学表达式计算算法
- 简单算法—计算表达式
- 计算后缀表达式的算法
- TongJI Online Judge预赛(3): Game
- Html 常用标志总结
- 实现页面的分帧显示
- 开源: 个人财务管理系统文档与源码下载
- TongJI Online Judge预赛(2): LOVE LETTER
- 表达式计算算法总结
- 同济OnlineJudge预赛题(一): Treenders
- 每天OnlineJudge之 “数素数”
- 堆栈小应用:配对
- 每天OnLineJudge 之 “蛇形矩阵 ”
- 每天OnLineJudge 之 “杨辉三角 ”
- 小问题,对递归重复调用的改进,一起来分享
- 在.net中使用Udp协议创建简单的聊天程序
- 以前我自己设计的“俄罗斯方块”,觉得挺有意思,今天贴出来
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
广州市康复中心
广州市几个区
广州市哪个省
广州市面积
广州市沙河
广州市的医院
广州市业余大学
广州市番禺长隆酒店
广州希诺酒店
广州58
广州563
58广州
买房 广州
广州房屋
广州房地产公司排名
广州地产公司排名
广州购房条件
广州房地产信息网
广州房产论坛
广州市学位房
广州经济适用房价格
房王网广州
广州学位房
增城房
广州护墙板批发
拣宝王
广州好
广州什么好玩
广州几个机场
广州有什么大学
广州有几个机场
广州北站有地铁吗
广州有什么好吃
广州有什么特产必带
广州有多少人口
广州有几个高铁站
广州离深圳有多远
广州有轨电车运营时间
广州东站有高铁吗
广州有哪些旅游景点
广州大学有哪些