|
|
|
|
@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
package mathlearning.service.MultipleChoiceGenerator;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Stack;
|
|
|
|
|
|
|
|
|
|
public class ComputingUnit {
|
|
|
|
|
String expression;
|
|
|
|
|
Stack <String> numbers = new Stack<>();
|
|
|
|
|
Stack <String> operators = new Stack<>();
|
|
|
|
|
|
|
|
|
|
ComputingUnit(String Question){
|
|
|
|
|
expression = Question;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void SplitAndChange(){
|
|
|
|
|
|
|
|
|
|
String[] split = expression.split(" ");
|
|
|
|
|
split = separateParentheses(split);
|
|
|
|
|
for(int i = 0 ; i < split.length ; i++){
|
|
|
|
|
if (split[i].charAt(0) == '√') {
|
|
|
|
|
String StrNum = split[i].substring(1);
|
|
|
|
|
double num = Math.sqrt(Double.parseDouble(StrNum));
|
|
|
|
|
split[i] = String.valueOf(num);
|
|
|
|
|
} else if (split[i].charAt(split[i].length()-1) == '²') {
|
|
|
|
|
String StrNum = split[i].substring(0, split[i].length()-1);
|
|
|
|
|
double result = Math.pow(Double.parseDouble(StrNum), 2);
|
|
|
|
|
split[i] = String.valueOf(result);
|
|
|
|
|
} else if ((split[i].charAt(0) == 's' || split[i].charAt(0) == 'c'
|
|
|
|
|
|| split[i].charAt(0) == 't' )) {
|
|
|
|
|
int index = split[i].indexOf(')');
|
|
|
|
|
int index2 = split[i].indexOf('(');
|
|
|
|
|
String StrNum = split[i].substring(index2 + 1, index);
|
|
|
|
|
double num = Double.parseDouble(SquOrRoot(StrNum));
|
|
|
|
|
double result = getFunc(split[i].charAt(0), num);
|
|
|
|
|
split[i] = String.valueOf(result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.expression = String.join(" ", split);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String[] separateParentheses(String[] originalArray) {
|
|
|
|
|
List<String> result = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
for (String item : originalArray) {
|
|
|
|
|
if (item.startsWith("(") && item.length() > 1) {
|
|
|
|
|
// 如果字符串以(开头且长度大于1,分离出(
|
|
|
|
|
result.add("(");
|
|
|
|
|
result.add(item.substring(1).trim());
|
|
|
|
|
} else if (item.endsWith(")") && item.length() > 1 &&
|
|
|
|
|
(item.charAt(0) != 's' && item.charAt(0) != 'c' && item.charAt(0) != 't')) {
|
|
|
|
|
// 如果字符串以)结尾且长度大于1,分离出)
|
|
|
|
|
result.add(item.substring(0, item.length() - 1).trim());
|
|
|
|
|
result.add(")");
|
|
|
|
|
} else if ((item.charAt(0) == 's' || item.charAt(0) == 'c' || item.charAt(0) == 't') &&
|
|
|
|
|
(item.endsWith(")") && item.charAt(item.length()-2) == ')')) {
|
|
|
|
|
result.add(item.substring(0, item.length() - 1).trim());
|
|
|
|
|
result.add(")");
|
|
|
|
|
} else {
|
|
|
|
|
// 其他情况保持不变
|
|
|
|
|
result.add(item);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result.toArray(new String[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String SquOrRoot(String StrNum){
|
|
|
|
|
if(StrNum.charAt(0) == '√'){
|
|
|
|
|
return String.valueOf(Math.sqrt(Double.parseDouble(StrNum.substring(1))));
|
|
|
|
|
} else if (StrNum.charAt(StrNum.length()-1) == '²') {
|
|
|
|
|
return String.valueOf(Math.pow(Double.parseDouble(StrNum.substring(0, StrNum.length()-1)), 2));
|
|
|
|
|
}else {
|
|
|
|
|
return StrNum;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private double getFunc(char func, double num){
|
|
|
|
|
switch (func) {
|
|
|
|
|
case 's':
|
|
|
|
|
return Math.sin(num);
|
|
|
|
|
case 'c':
|
|
|
|
|
return Math.cos(num);
|
|
|
|
|
case 't':
|
|
|
|
|
return Math.tan(num);
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void priority(String operator){
|
|
|
|
|
if(operators.isEmpty() || operators.peek().equals("(")){
|
|
|
|
|
operators.push(operator);
|
|
|
|
|
}else{
|
|
|
|
|
if((operators.peek().equals("+")|| operators.peek().equals("-")) &&
|
|
|
|
|
(operator.equals("×") || operator.equals("÷"))){
|
|
|
|
|
operators.push(operator);
|
|
|
|
|
}else{
|
|
|
|
|
CulAndPushOperator(operator);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void CulAndPushOperator(String operator){
|
|
|
|
|
String num1 = numbers.pop();
|
|
|
|
|
String num2 = numbers.pop();
|
|
|
|
|
String operator1 = operators.pop();
|
|
|
|
|
operators.push(operator);
|
|
|
|
|
String result = SingleCul(num2, operator1, num1);
|
|
|
|
|
numbers.push(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String Compute(){
|
|
|
|
|
String[] spilt = expression.split(" ");
|
|
|
|
|
for (int i = 0; i < spilt.length; i++){
|
|
|
|
|
if(spilt[i].equals("+") || spilt[i].equals("-") ||
|
|
|
|
|
spilt[i].equals("×") || spilt[i].equals("÷") ||
|
|
|
|
|
spilt[i].equals("(") ){//处理运算符
|
|
|
|
|
if( spilt[i].equals("(")){
|
|
|
|
|
operators.push(spilt[i]);
|
|
|
|
|
}else{
|
|
|
|
|
priority(spilt[i]);
|
|
|
|
|
}
|
|
|
|
|
}else if(spilt[i].equals(")")){
|
|
|
|
|
String tempResult = numbers.pop();
|
|
|
|
|
while (!operators.peek().equals("(")){
|
|
|
|
|
String operator = operators.pop();
|
|
|
|
|
String num1 = numbers.pop();
|
|
|
|
|
tempResult = SingleCul(num1, operator, tempResult);
|
|
|
|
|
}
|
|
|
|
|
if(operators.peek().equals("(")){
|
|
|
|
|
operators.pop();
|
|
|
|
|
}
|
|
|
|
|
numbers.push(tempResult);
|
|
|
|
|
} else {
|
|
|
|
|
numbers.push(spilt[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return CulWithoutPriority();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String CulWithoutPriority(){
|
|
|
|
|
if(numbers.isEmpty()){
|
|
|
|
|
return "0";
|
|
|
|
|
}
|
|
|
|
|
String result = numbers.pop();
|
|
|
|
|
while (!operators.isEmpty() && !numbers.isEmpty()){
|
|
|
|
|
String num1 = numbers.pop();
|
|
|
|
|
String operator = operators.pop();
|
|
|
|
|
result = SingleCul(num1, operator, result);
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getAnswer(){
|
|
|
|
|
SplitAndChange();
|
|
|
|
|
return Compute();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String SingleCul(String nowResult, String operator, String num){
|
|
|
|
|
// 使用 trim() 去除首尾空格
|
|
|
|
|
// 使用 split("\\s+") 按空格分割,只取第一个元素(数字)
|
|
|
|
|
String cleanNowResult = nowResult.trim().split("\\s+")[0];
|
|
|
|
|
String cleanNum = num.trim().split("\\s+")[0];
|
|
|
|
|
|
|
|
|
|
// 现在可以安全地解析数字了
|
|
|
|
|
Double result = Double.parseDouble(cleanNowResult);
|
|
|
|
|
switch (operator) {
|
|
|
|
|
case "+":
|
|
|
|
|
result += Double.parseDouble(cleanNum);
|
|
|
|
|
break;
|
|
|
|
|
case "-":
|
|
|
|
|
result -= Double.parseDouble(cleanNum);
|
|
|
|
|
break;
|
|
|
|
|
case "×":
|
|
|
|
|
result *= Double.parseDouble(cleanNum);
|
|
|
|
|
break;
|
|
|
|
|
case "÷":
|
|
|
|
|
result /= Double.parseDouble(cleanNum);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return String.valueOf(result);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|