人傻就要多动脑,为了完成计算器的运算功能,自己之前想的算法过于麻烦而且要添加很多健全代码,百度了很多东西,发现后缀表达式很好地解决了算术表达式的解析问题,然而看算法花了一晚上加早上一节课的时间,不过终于还是弄懂了。
先来说说后缀表达式。我们经常使用的算术表达式被称为中缀表达式,下面来举个例子看看后缀表达式的写法:
中缀表达式:(2+5)*6
后缀表达式:2 5 + 6 *
从左向右读,不考虑运算符优先顺序,遇到第一个运算符时将运算符前面的两个数以这个运算符的属性进行运算,因此第一次运算的结果为7 6 *,然后同样的进行第二次运算,结果为42。
后缀运算符的好处是不用考虑运算符的优先级,通过嵌套函数运算即可完成所求结果。
真正有点难度的是中缀表达式转换为后缀表达式的方法,下面我具体说说算法思想,因为不涉及到指针,因此所有编程语言均适用。
在这里需要用到栈的思想,故不懂栈的童鞋请自行学习下栈的基础知识。
具体算法流程:
1、新建一个空栈
2、新建一个空字符串用来存后缀表达式
3、输入表达式并存为字符数组
4、从左往右遍历字符数组,判断得到的字符并进行操作
(1)若字符为’(’则入栈;
(2)若字符为’)’则依次出栈,直到出栈字符为’(’为止;
(3)若字符为’0’-‘9’,则加入字符串;
(4)若字符为’+’,则循环判断栈顶元素是否为’+’或’-’或’*’或’/’,若是则出栈并加入字符串,循环结束后自身入栈;
(5)若字符为’-’,则循环判断栈顶元素是否为’-’或’*’或’/’,若是则出栈并加入字符串,循环结束后自身入栈;
(6)若字符为’*’,则循环判断栈顶元素是否为’*’或’/’,若是则出栈并加入字符串,循环结束后自身入栈;
(7)若字符为’/’,则循环判断栈顶元素是否为’/’,若是则出栈并加入字符串,循环结束后自身入栈;
5、若遍历完成,则将栈中字符依次出栈加入字符串
6、所得到的字符串就是后缀表达式。
具体实例:1+(2+6)*4
1、1+(2+6)*4
字符串:
1 |
|
|
|
|
|
|
|
栈:
|
|
|
|
|
|
|
|
2、1+(2+6)*4
字符串:
1 |
|
|
|
|
|
|
|
栈:
+ |
|
|
|
|
|
|
|
3、1+(2+6)*4
字符串:
1 |
|
|
|
|
|
|
|
栈:
+ | ( |
|
|
|
|
|
|
4、1+(2+6)*4
字符串:
1 | 2 |
|
|
|
|
|
|
栈:
+ | ( |
|
|
|
|
|
|
5、1+(2+6)*4
字符串:
1 | 2 |
|
|
|
|
|
|
栈:
+ | ( | + |
|
|
|
|
|
6、1+(2+6)*4
字符串:
1 | 2 | 6 |
|
|
|
|
|
栈:
+ | ( | + |
|
|
|
|
|
6、1+(2+6)*4
字符串:
1 | 2 | 6 | + |
|
|
|
|
栈:
+ |
|
|
|
|
|
|
|
6、1+(2+6)*4
字符串:
1 | 2 | 6 | + |
|
|
|
|
栈:
+ | * |
|
|
|
|
|
|
6、1+(2+6)*4
字符串:
1 | 2 | 6 | + | 4 |
|
|
|
栈:
+ | * |
|
|
|
|
|
|
7、遍历结束,所有元素出栈
字符串:
1 | 2 | 6 | + | 4 | * | + |
|
栈:
|
|
|
|
|
|
|
|
因此最后得到的后缀表达式为1 2 6 + 4 * +
为了保险,我们再计算一次:1+(2+6)*4 = 33
后缀:
1、1 8 4 * +
2、1 32 +
3、33
如果有更好的解析算术表达式的方法欢迎私聊~