我正在Android Studio中使用Java开发一个科学计算器.我使用Streatergy设计模式来处理操作,并将分流堆场算法用于Calculate函数,因为它遵循BODMAS规则.
我有两个问题.
- BODMAS规则运行良好,但如果存在相同的优先操作,则它不遵循从左到右的规则.
- 如何在其中包含"cos"、"sin"等函数?它应该遵循BODMAS规则.
Bellow是我到目前为止开发的代码.我关心的是基于char数组实现的算法.如果我要识别"cos",我必须搜索字母‘c’或任何其他函数,首先搜索字母,然后遍历下一个元素,找到完整的函数名.有没有其他方法可以做到这一点?还有它是如何在从左到右的规则中发挥作用的,这些科学功能.
以下是我到目前为止开发的代码.
如有任何建议,我们将不胜感激.
谢谢.
public class ScientificCalculator {
public Operation operation;
public ScientificCalculator(Operation operation){
this.operation = operation;
}
public double calculate(String exp) {
char[] tokens = exp.toCharArray();
Queue values = new LinkedList<>();
Stack ops = new Stack();
for (int i = 0; i < tokens.length; i++) {
if (tokens[i] == ' ') {
continue;
}
else if (Character.isDigit(tokens[i])) {
StringBuffer sbuf = new StringBuffer();
while (i < tokens.length && Character.isDigit(tokens[i])) {
sbuf.append(tokens[i]);
if ((i + 1) < tokens.length && Character.isDigit(tokens[i+1])) {
i++;
} else {
break;
}
}
values.add(Double.parseDouble(sbuf.toString()));
} else if (tokens[i] == 'x' || tokens[i] == '-' || tokens[i] == '/' || tokens[i] == '+') {
if (ops.isEmpty()) {
ops.push(tokens[i]);
continue;
}
char op1 = ops.peek();
boolean hasHighPrecedence = hasPrecedence(op1, tokens[i]);
if (hasHighPrecedence) {
char op = ops.pop();
values.add(op);
ops.push(tokens[i]);
} else {
ops.push(tokens[i]);
}
} else if (tokens[i] == '(') {
ops.push(tokens[i]);
} else if (tokens[i] == ')') {
while (ops.peek() != '(') {
values.add(ops.pop());
}
ops.pop();
}
}
while (!ops.isEmpty()) {
values.add(ops.pop());
}
Stack numStack = new Stack<>();
while (!values.isEmpty()) {
Object val = values.poll();
if (val instanceof Character) {
char v = (Character) val;
if (v == 'x' || v == '-' || v == '/' || v == '+') {
double num2, num1;
num1 = numStack.pop();
num2 = numStack.pop();
double ans = applyOp(v, num1, num2);
numStack.push(ans);
}
} else {
double num = (double) val;
numStack.push(num);
}
}
return numStack.pop();
}
public static double applyOp(char op, double b, double a) {
switch (op) {
case '+':
return new addition().calculate(a,b);
case '-':
return new subtraction().calculate(a,b);
case 'x':
return new multiplication().calculate(a,b);
case '/':
if (b == 0)
throw new
IllegalArgumentException("Cannot divide by zero");
return new division().calculate(a,b);
}
return 0;
}
public static boolean hasPrecedence(char op1, char op2) {
if ((op1 == 'x' || op1 == '/') && (op2 == '+' || op2 == '-')){
return true;
} else {
return false;
}
}
}