数据结构学习实录三—中缀表达式转后缀表达式(C++)
来源:互联网 发布:ubuntu install kde 编辑:程序博客网 时间:2024/05/16 23:53
精力几欲透支,一天写三篇计算机博文不是盖的,废话不多说,老夫还有一口气,上!
栈大家都懂了吧,此物想来也不难,老夫今日几欲吐血,就不详细介绍了,不会的男同学百度,女同学私聊。
那么栈是非常有用的一种数据结构思想,尤其在其解决迷宫问题时显现出难以替代的优越性,并且在解决中缀表达式转后缀表达式中也意义重大。
什么是中缀表达式?
你从小就写,普通的算式就是中缀表达式,比如A+B*(C-D)-E/F;简单吧,见过吧,自己写过无数遍了吧。那么,我们知道,这种表达式是为了计算数字,人类操作和计算非常方便,但是计算机不同,计算机可不喜欢这种表达式,他没有那么复杂的直接运算,他希望能够使用后缀表达式。那么上面的式子转成后缀表达式是什么样的呢?
ABCD-*+EF/-;稀奇吧,古怪吧,没见过吧,那就对啦!嘿嘿,怎么算?看老夫娓娓道来。
你从前往后读,ABCD减号!看见运算符了吧,把运算符前面两个数字拿出来,C和D,好,把减号放中间,C-D,成功了,然后把CD-换成C-D,C-D当整体看就是AB(C-D)*+EF/-;
同样从前往后看,C-D已经是一个数字了啊,当整体看。A B (C-D) 乘号!取乘号前两个数字 B (C-D),乘号放中间,成B*(C-D),然后把B*(C-D)当成整体放回,变成AB*(C-D)+EF/-;
然后,再从前往后看AB*(C-D)加号!取运算符前两个数字,A和B*(C-D);变成A+B*(C-D);继续,A+B*(C-D)EF除号!取运算符前两个数字E和F,加上除号变成E/F,放回变成A+B*(C-D)E/F继续读;A+B*(C-D)E/F减号!取运算符前两个数字,A+B*(C-D)和E/F,换上减号,成A+B*(C-D)-E/F;是不是和中缀表达式一样了。那么这么做有什么意义呢?
我们先来看下中缀表达式的计算法则:
1.有括号要先算括号里的。
2.乘除比加减优先级要高。
3.乘方与开方比乘除优先级要高。
4.计算顺序根据题目自行确定。
中缀表达式不能使用较为简单的逻辑进行描述,所以如果使用中缀表达式进行运算,编程实现无疑是困难了许多。
我们分析下,后缀表达式的运算法则非常简单
1.从前往后扫描,数字不做处理。
2.遇到运算符,则取运算符前两个数字进行计算。
3.用计算结果替代原来两个数字和运算符,并从新从第一步开始运行,直到只有一个数字为止。
我们可以看到,这样的话,一个复杂表达式的计算就被转成循环和简单条件的判定了,非常利于编程实现。
那么我们讨论下,中缀表达式如何转后缀表达式呢?
其实我们可以使用二元树进行后续遍历实现,不过由于还没有学到树,并且实现很简单就先留给读者自行解决了,以后我再做讲解。
在此我们使用栈对+-*/()进行实现,其他的运算符暂不实现。
额 讲解好难 怎么讲?
首先 我们对所有运算符加上优先级判定。且优先级分为内优先和外优先
然后呢,我们在表达式前后加上‘#’作为标注,比如 A+B*(C-D)-E/F;就会变成#A+B*(C-D)-E/F#,方便判断。
首先讲解规则
1.生成栈区,用于临时存放运算符。
2.遇到数字,直接输出到后缀表达式。
3.当栈为空时,运算符或‘#’直接进栈
4.遇到运算符,若栈顶元素的内优先数小于遇到运算符的外优先数,则允许外运算符入栈(压栈);若栈顶元素的内优先数大于遇到运算符的外优先数,则将栈顶运算符输出(出栈),再将外运算符进行第四步判断。括号也算运算符。若栈顶元素的内优先数等于遇到运算符的外优先数,则将栈顶运算符弹出,两个运算符直接丢弃,不做输出。
四条基本规则解释完毕,接下来编程实现。
为了程序便于移植,主函数不做过多操作,仅用于数据传输。
// 中缀表达式转后缀表达式.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include"iostream"using namespace std;typedef struct SqStack{char date[30];int top=0;}SqStack;//用于确定符号的优先级 i=true代表内优先,否则为外优先,返回值为-1时,代表是数字。int mynum(char a, bool i){if (a == '#')return 0;if (a == '(')if (i == true)return 1;elsereturn 6;if (a == ')')if (i == true)return 6;elsereturn 1;if (a == '*'||a=='/')if (i == true)return 5;elsereturn 4;if (a == '+' || a == '-')if (i == true)return 3;elsereturn 2;return -1;}//对栈进行操作的函数void transform(char* oldl, char* inew){int num = 0,inum=0,n=0;SqStack a;//生成栈区char old[30];//对表达式前后加#old[0] = '#';int ii = 0;for (ii = 0; oldl[ii] != '\0'; ii++){old[ii + 1] = oldl[ii];}old[ii+1] = '#';old[ii + 2] = '\0';//加#结束for (int i = 0; i < 30; i++){a.date[i] = 0;}//栈区清空a.date[a.top] = '#';//首#入栈//对表达式进行转换for (int i = 1; old[i] != '\0'; i++){num = mynum(old[i], 0);if (num != -1){inum = mynum(a.date[a.top], 1);if (num > inum){a.top++;a.date[a.top] = old[i];}else if (num == inum){a.date[a.top] = 0;a.top--;}else{inew[n] = a.date[a.top];n++;a.top--;i--;}}else{inew[n] = old[i];n++;}}inew[n] = '\0';}int main(){char s[30] = "A+B*(C-D)-E/F";char ss[30];transform(s, ss);cout << ss;system("pause"); return 0;}
本文为作者原创,任何形式的引用、转载等操作请提前获得作者授权,未经授权,禁止以任何形式引用或转载此文。
- 数据结构学习实录三—中缀表达式转后缀表达式(C++)
- 数据结构学习---中缀表达式转后缀表达式(c++)
- 【数据结构学习】中缀表达式转后缀表达式
- 数据结构学习实录四—后缀表达式的计算(C++)
- 《数据结构》中缀表达式转后缀表达式
- 【数据结构】中缀表达式转后缀表达式
- 数据结构栈之中缀表达式转后缀
- 数据结构堆栈之中缀表达式转后缀
- 中缀表达式转后缀表达式 (中缀表达式的计算)
- 数据结构--中缀表达式转为后缀表达式(逆波兰表达式)
- 【数据结构】中缀表达式|后缀表达式|前缀表达式
- 数据结构-前缀、中缀、后缀表达式
- 数据结构-前缀、中缀、后缀表达式
- 数据结构前缀,后缀,中缀表达式
- 中缀表达式转后缀表达式(数组)
- 数据结构中缀表达式转后缀表达式以及后缀转中缀表达式
- 中缀转后缀表达式
- 表达式中缀转后缀
- iOS
- Layout POJ
- 操作系统刷题(十一)
- The Maximum Mean Discrepancy
- 数据库设计原理知识--B树、B-树、B+树、B*树都是什么
- 数据结构学习实录三—中缀表达式转后缀表达式(C++)
- 编译工具的php项目(二)
- 游戏中间的心理学
- 1天 的每个时辰与 5行的关系
- java反射的一些调试
- XMLHttpRequest用法详解
- Java面试题,List集合中根据对象的某一属性排序
- Unity获取当前手机电量的方法
- 学习小米的open-falcon