|
|
|
|
@ -0,0 +1,139 @@
|
|
|
|
|
// HighQueSeting.java
|
|
|
|
|
package com.example.myapp.service;
|
|
|
|
|
|
|
|
|
|
import com.example.myapp.model.Expression;
|
|
|
|
|
|
|
|
|
|
public class HighQueSeting extends AbstractQuestionSeting {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public String addParenthesesIfNeeded(Expression child, String parentOp, boolean isRightChild) {
|
|
|
|
|
if (child.mainOperator == null
|
|
|
|
|
|| child.mainOperator.equals("²") || child.mainOperator.equals("√")
|
|
|
|
|
|| child.mainOperator.equals("sin") || child.mainOperator.equals("cos")
|
|
|
|
|
|| child.mainOperator.equals("tan")) {
|
|
|
|
|
return child.expression;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int parentPriority = getPriority(parentOp);
|
|
|
|
|
int childPriority = getPriority(child.mainOperator);
|
|
|
|
|
|
|
|
|
|
if (childPriority < parentPriority) {
|
|
|
|
|
return "(" + child.expression + ")";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (isRightChild && (parentOp.equals("-") || parentOp.equals("/"))) {
|
|
|
|
|
if (parentPriority == childPriority) {
|
|
|
|
|
return "(" + child.expression + ")";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return child.expression;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Expression applyUnary(Expression child, String op) {
|
|
|
|
|
switch (op) {
|
|
|
|
|
case "²":
|
|
|
|
|
if (child.mainOperator == null) {
|
|
|
|
|
return new Expression(child.expression + "²", child.value * child.value, "²");
|
|
|
|
|
}
|
|
|
|
|
return new Expression("(" + child.expression + ")²", child.value * child.value, "²");
|
|
|
|
|
case "√":
|
|
|
|
|
String numStr = getNumberForSqrt();
|
|
|
|
|
child = new Expression(numStr, parseNumber(numStr), null);
|
|
|
|
|
|
|
|
|
|
double sqrtValue = Math.sqrt(child.value);
|
|
|
|
|
if (child.mainOperator == null) {
|
|
|
|
|
return new Expression("√" + child.expression, sqrtValue, "√");
|
|
|
|
|
}
|
|
|
|
|
return new Expression("√(" + child.expression + ")", sqrtValue, "√");
|
|
|
|
|
case "sin":
|
|
|
|
|
int[] sinAngles = {0, 30, 45, 60, 90, 120, 135, 150, 180};
|
|
|
|
|
int sinAngle = sinAngles[rand.nextInt(sinAngles.length)];
|
|
|
|
|
child = new Expression(String.valueOf(sinAngle), sinAngle, null);
|
|
|
|
|
return new Expression("sin(" + child.expression + "°)",
|
|
|
|
|
Math.sin(Math.toRadians(child.value)), "sin");
|
|
|
|
|
case "cos":
|
|
|
|
|
int[] cosAngles = {0, 30, 45, 60, 90, 120, 135, 150, 180};
|
|
|
|
|
int cosAngle = cosAngles[rand.nextInt(cosAngles.length)];
|
|
|
|
|
child = new Expression(String.valueOf(cosAngle), cosAngle, null);
|
|
|
|
|
return new Expression("cos(" + child.expression + "°)",
|
|
|
|
|
Math.cos(Math.toRadians(child.value)), "cos");
|
|
|
|
|
case "tan":
|
|
|
|
|
int[] tanAngles = {0, 30, 45, 60, 120, 135, 150, 180};
|
|
|
|
|
int tanAngle = tanAngles[rand.nextInt(tanAngles.length)];
|
|
|
|
|
child = new Expression(String.valueOf(tanAngle), tanAngle, null);
|
|
|
|
|
double tanValue = Math.tan(Math.toRadians(child.value));
|
|
|
|
|
if (Math.abs(tanValue) > 1000) {
|
|
|
|
|
tanValue = tanValue > 0 ? 1000 : -1000;
|
|
|
|
|
}
|
|
|
|
|
return new Expression("tan(" + child.expression + "°)", tanValue, "tan");
|
|
|
|
|
default:
|
|
|
|
|
return child;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Expression setQuestion(int count) {
|
|
|
|
|
Expression result = firstSetQuestion(count);
|
|
|
|
|
// 确保高中题目包含至少一个三角函数
|
|
|
|
|
int attempts = 0;
|
|
|
|
|
while (!result.expression.contains("sin") && !result.expression.contains("cos")
|
|
|
|
|
&& !result.expression.contains("tan") && attempts < 10) {
|
|
|
|
|
result = firstSetQuestion(count);
|
|
|
|
|
attempts++;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Expression probability(Expression result) {
|
|
|
|
|
// 高中阶段:40%概率添加一元运算
|
|
|
|
|
if (rand.nextDouble() < 0.4) {
|
|
|
|
|
String[] unaryOps = {"²", "√", "sin", "cos", "tan"};
|
|
|
|
|
String unaryOp = unaryOps[rand.nextInt(unaryOps.length)];
|
|
|
|
|
result = applyUnary(result, unaryOp);
|
|
|
|
|
result.mainOperator = unaryOp;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Expression firstSetQuestion(int count) {
|
|
|
|
|
if (count == 1) {
|
|
|
|
|
String numStr = getRandomNumber();
|
|
|
|
|
Expression expr = new Expression(numStr, parseNumber(numStr), null);
|
|
|
|
|
expr = probability(expr);
|
|
|
|
|
return expr;
|
|
|
|
|
}
|
|
|
|
|
int leftCount = 1 + rand.nextInt(count - 1);
|
|
|
|
|
int rightCount = count - leftCount;
|
|
|
|
|
|
|
|
|
|
Expression left = firstSetQuestion(leftCount);
|
|
|
|
|
Expression right = firstSetQuestion(rightCount);
|
|
|
|
|
|
|
|
|
|
String op = getRandomOperator();
|
|
|
|
|
double value = 0;
|
|
|
|
|
switch (op) {
|
|
|
|
|
case "+":
|
|
|
|
|
value = left.value + right.value;
|
|
|
|
|
break;
|
|
|
|
|
case "-":
|
|
|
|
|
value = left.value - right.value;
|
|
|
|
|
break;
|
|
|
|
|
case "*":
|
|
|
|
|
value = left.value * right.value;
|
|
|
|
|
break;
|
|
|
|
|
case "/":
|
|
|
|
|
if (Math.abs(right.value) < 1e-10) {
|
|
|
|
|
return firstSetQuestion(count);
|
|
|
|
|
}
|
|
|
|
|
value = left.value / right.value;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String leftExpr = addParenthesesIfNeeded(left, op, false);
|
|
|
|
|
String rightExpr = addParenthesesIfNeeded(right, op, true);
|
|
|
|
|
|
|
|
|
|
Expression result = new Expression(leftExpr + " " + op + " " + rightExpr, value, op);
|
|
|
|
|
result = probability(result);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|