预处理
- 判断表达式的合法性:1.如果表达式长度为1,且不是数字,2.如果表达式中开头一位为运算符(负号(减号)和左括号除外),3.如果是最后一位是运算符(右括号除外),4.1.1 小数点左、右任意一边不为数字,左括号”(“后面有:+ x ÷ ) .,左括号”(“前面有:数字、”)” ,可以认为是乘法,在左括号”(“前面插入”x”,右括号”)”前面为:+、- x ÷ . (,4.4.1 @”+”,@”-“,@”x”,@”÷”,@”.” 左边或右边包含 @”+”,@”-“,@”x”,@”÷”,@”.”,5. 括号不匹配的情况,
- 在数字和符号之间插入空格,以空格为分隔符去除字符串中的数字和符号,放入数组Array中,
表达式计算
基本思想:
- 优先级:括号 > 乘除 > 加减
- 若没有括号,四则运算,从前向后先算表达式中的乘除,再最后一次算一遍加减。1+2*3-4÷2
- 若有括号,非嵌套时,将括号对内部的表达式按四则运算计算,有括号嵌套,则利用递归思想,从最内层括号向外计算
程序实现:
构建两个栈,数栈和操作符栈。
如果是数字,
- 操作符栈为空,或栈顶(数组的最后一个对象)为加减,则加入数栈
- 否则,若操作符栈为乘除,则加入数栈,,判断数栈中倒数第2个元素是否为数字,若是,则进行计算,并将结果加入到数栈中,若不是数字(而是左括号)则继续后续遍历。
如果是操作符,入操作符栈
如果是左边括号:入数栈
如果是右边括号:查找左括号在numberArray中的位置,表达式中左括号后面首个操作符在operatorArray中的位置,计算括号内部结果,用结果代替左括号的位置,然后判断前面的操作符是否为乘除,若是,则继续计算。
最后剩下加减表达式,这时再来一次加减计算:从左到右遍历计算。
1 + 2 *(3 + 4 * 5)
计算过程 | 数栈 | 操作符栈 |
---|---|---|
1 | 1 | |
2 | 1 | + |
3 | 1、2 | + |
4 | 1、2 | +、* |
5 | 1、2、( | +、* |
6 | 1、2、(、3 | +、* |
7 | 1、2、(、3 | +、*、+ |
8 | 1、2、(、3、4 | +、*、+ |
9 | 1、2、(、3、4 | +、*、+、* |
10.1 | 1、2、(、3、4、5 | +、*、+、* |
10.2 | 1、2、(、3、20 | +、*、+ |
11 | 1、2、23 | +、* |
12 | 1、46 | + |
13 | 47 |