科学计算器
完整代码及测试数据
问题简介
完成一个科学计算器,相比简易计算器增加了一些三角函数和幂函数以及指数函数的计算。完成一个可以使用的科学计算器,需要满足支持下面的运算符。
运算符 | 解释 | 运算符 | 解释 |
---|---|---|---|
+ | 1+1=2 | √ | 开方. √4=2 |
- | 2-1=1 or -1-2=-3 | ( | 左括号 |
* | 2 * 2 = 4 | ) | 右括号 |
/ | 4 / 2 = 2 | ! | 阶乘。3!=123=6 |
ln | ln(e)=1,以e为底的对数 | log | 以2为底的对数。log(4)=2 |
sin | sin(30)=0.5, 正弦函数,输入是角度数。 | arcsin | arcsin(0.5)=30, 反正弦函数,输出是角度数 |
cos | cos(90)=0, 余弦函数,输入是角度数。 | arccos | arcsin(0)=90, 反余弦函数,输出是角度数 |
tan | tan(45)=1,正切函数,输入是角度数。 | arctan | arcsin(1)=45, 反正切函数,输出是角度数 |
^ | 指数运算。2^(3)=8; 4^(0.5)=2; 4^(-1/2=0.5 |
Example
序号 | input | output | 解释 |
---|---|---|---|
v1 | 1+1+1+1 | 4 | 符号优先级相同,先算前面再算后面 |
v2 | 2-1*2 | 0 | 先算乘除,再算加减 |
v3 | (2-1)*2 | 2 | 先算括号里面的数 |
v4 | (2-1*2+14/2)+√9 | 10 | 先算括号,再算其他,开方的优先级比乘除高 |
v5 | (2+3)4+√9(1/2+((1+1)*2)) | 33.5 | 同v4 |
v6 | -2-3 | -5 | 第一个’-‘是表示负数,第二个’-'是运算符 |
v7 | -2+(-3)*5 | -17 | 第一个’-‘是表示负数,括号里面的第二个’-'也表示负数 |
v8 | √9*√9+√9 | 12 | 开方的优先级高于乘除,乘除的优先级高于加减 |
v9 | sin(2^6+26) | 1 | sin函数是一个单值运算函数,先算括号,根据优先级进行计算 |
v10 | 2^6 | 64 | 指数运算 |
v11 | 4^(-1/2) | 0.5 | 指数元素 |
v12 | 2^log(8) | 8 | 指数运算和对数运算 |
v13 | ln(e*e) | 2 | 以e为底的对数运算 |
v14 | (5!-8^(1/2))*e | 318.505 | 阶乘和指数运算的组合 |
v15 | -232(-1)+22^3+3! | 259 | 多种运算的组合 |
v16 | 2+arcsin(log(2.0))+5+2^(2)+(-log(2)) | 100 | 多种元素的组合 |
解法
维护两个栈,分别是符号栈和数值栈。
- 首先遍历字符串,进行相应的操作;
- 遍历完字符串后,还需要进行相应的操作以清空符号栈,最后保证数值栈剩余最后一个数字为答案。
步骤和之前简易计算器相同,参照之前的流程图,这里不再重复。
有以下几个地方需要注意:
处理负号
所有的负号都可以转换成减法操作,识别出来是负号之后,在负号前补0即可。如何当前的’-'是负号,有两个条件:
- ’-'在输入表达式的第一位(stack_num为空)
- ’-'之前的字符不是数字(且不能是‘)’和‘!’),可以想到,
(-8)
需要补0,但8^2-9、(8)-9、8!-9
不需要补0;
Input: -2-3 ---> Format_input: 0-2-3
Input: 3+(-2)*(-1) ---> Format_input: 3+(0-2)*(0-1)
符号之间的优先级
'+': {
'+':-1, '-':-1, '*':-1, '/':-1, '√':-1, '(':1, ')':-1, '!':-1, '^':-1, 'ln':-1, 'log':-1, 'sin':-1, 'cos':-1, 'tan':-1, 'arcsin':-1, 'arccos':-1, 'arctan':-1},
'-': {
'+':-1, '-':-1, '*':-1, '/':-1, '√':-1, '(':1, ')':-1, '!':-1, '^':-1, 'ln':-1, 'log':-1, 'sin':-1, 'cos':-1, 'tan':-1, 'arcsin':-1, 'arccos':-1, 'arctan':-1},
'*': {
'+': 1, '-': 1, '*':-1, '/':-1, '√':-1, '(':1, ')':-1, '!':-1, '^':-1, 'ln':-1, 'log':-1, 'sin':-1, 'cos':-1, 'tan':-1, 'arcsin':-1, 'arccos':-1, 'arctan':-1},
'/': {
'+': 1, '-': 1, '*':-1, '/':-1, '√':-1, '(':1, ')':-1, '!':-1, '^':-1, 'ln':-1, 'log':-1, 'sin':-1, 'cos':-1, 'tan':-1, 'arcsin':-1, 'arccos':-1, 'arctan':-1},
'√': {
'+': 1, '-': 1, '*': 1, '/': 1, '√':-1, '(':1, ')':-1, '!':-1, '^':-1, 'ln':-1, 'log':-1, 'sin':-1, 'cos':-1, 'tan':-1, 'arcsin':-1, 'arccos':-1, 'arctan':-1},
'(': {
'+': 1, '-': 1, '*': 1, '/': 1, '√': 1, '(':1, ')': 0, '!':-1, '^': 1, 'ln': 1, 'log': 1, 'sin': 1, 'cos': 1, 'tan': 1, 'arcsin': 1, 'arccos': 1, 'arctan': 1},
')': {
'+':-1, '-':-1, '*':-1, '/':-1, '√':-1, '(':0, ')':-1, '!':-1, '^':-1, 'ln':-1, 'log':-1, 'sin':-1, 'cos':-1, 'tan':-1, 'arcsin':-1, 'arccos':-1, 'arctan':-1},
'!': {
'+': 1, '-': 1, '*': 1, '/': 1, '√': 1, '(':1,