package Base; import java.util.HashMap; import java.util.Random; import java.util.Stack; public class Question { private int number; private String content; private String type; private String answer; private String[] options; private final Random ra= new Random(); public static final HashMap trigValues = new HashMap<>(); static { // 15° trigValues.put("sin(15°)", "√2*(√3-1)/4"); trigValues.put("cos(15°)", "√2*(√3+1)/4"); trigValues.put("tan(15°)", "(2-√3)"); trigValues.put("sin²(15°)", "(2-√3)/4"); trigValues.put("cos²(15°)", "(2+√3)/4"); trigValues.put("tan²(15°)", "(7-4*√3)"); // 22.5° trigValues.put("sin(22.5°)", "√0.59/2"); //√(2-√2)/2 trigValues.put("cos(22.5°)", "√3.41/2"); //√(2+√2)/2 trigValues.put("tan(22.5°)", "(√2-1)"); trigValues.put("sin²(22.5°)", "(2-√2)/4"); trigValues.put("cos²(22.5°)", "(2+√2)/4"); trigValues.put("tan²(22.5°)", "(3-2*√2)"); // 75° trigValues.put("sin(75°)", "√2*(√3+1)/4"); trigValues.put("cos(75°)", "√2*(√3-1)/4"); trigValues.put("tan(75°)", "(2+√3)"); trigValues.put("sin²(75°)", "(2+√3)/4"); trigValues.put("cos²(75°)", "(2-√3)/4"); trigValues.put("tan²(75°)", "(7+4*√3)"); // 105° trigValues.put("sin(105°)", "√2*(√3+1)/4"); trigValues.put("cos(105°)", "√2*(1-√3)/4"); trigValues.put("tan(105°)", "(0-(2+√3))"); trigValues.put("sin²(105°)", "(2+√3)/4"); trigValues.put("cos²(105°)", "(2-√3)/4"); trigValues.put("tan²(105°)", "(7+4*√3)"); // 120° trigValues.put("sin(120°)", "√3/2"); trigValues.put("cos(120°)", "(0-1/2)"); trigValues.put("tan(120°)", "(0-√3)"); trigValues.put("sin²(120°)", "3/4"); trigValues.put("cos²(120°)", "1/4"); trigValues.put("tan²(120°)", "3"); // 135° trigValues.put("sin(135°)", "√2/2"); trigValues.put("cos(135°)", "(0-√2/2)"); trigValues.put("tan(135°)", "(0-1)"); trigValues.put("sin²(135°)", "1/2"); trigValues.put("cos²(135°)", "1/2"); trigValues.put("tan²(135°)", "1"); // 150° trigValues.put("sin(150°)", "1/2"); trigValues.put("cos(150°)", "(0-√3/2)"); trigValues.put("tan(150°)", "(0-√3/3)"); trigValues.put("sin²(150°)", "1/4"); trigValues.put("cos²(150°)", "3/4"); trigValues.put("tan²(150°)", "1/3"); // 210° trigValues.put("sin(210°)", "(0-1/2)"); trigValues.put("cos(210°)", "(0-√3/2)"); trigValues.put("tan(210°)", "√3/3"); trigValues.put("sin²(210°)", "1/4"); trigValues.put("cos²(210°)", "3/4"); trigValues.put("tan²(210°)", "1/3"); // 300° trigValues.put("sin(300°)", "(0-√3/2)"); trigValues.put("cos(300°)", "1/2"); trigValues.put("tan(300°)", "(0-√3)"); trigValues.put("sin²(300°)", "3/4"); trigValues.put("cos²(300°)", "1/4"); trigValues.put("tan²(300°)", "3"); } public Question(int number, String content, String type) { this.number = number; this.content = content; this.type = type; options=new String[4]; } public int getNumber() { return number; } public String getContent() { return content; } public String getType() { return type; } public String getAnswer() {return answer;} public String getOptions(int i) {return options[i];} @Override public String toString(){ return this.number+". "+this.content+" = ?"; } public void set_options(){ answer=calculate(this.content); int which=ra.nextInt(4); options[which]=answer; for (int i=0;i<4;i++) { if (i != which) { if (this.type.equals("高中")) { options[i] = answer.equals("不可解") ? String.format("%.2f", Math.sqrt(3) * ra.nextInt(10) + ra.nextDouble(1)) : String.format("%.2f", Double.parseDouble(answer) + Math.sqrt(2) * ra.nextInt(5)); } else { if (Double.parseDouble(answer) ==Math.floor(Double.parseDouble(answer)) ) { options[i] = answer.equals("不可解") ? String.valueOf((int) ra.nextInt(1000) + ra.nextInt(10)) : String.valueOf((int) Double.parseDouble(answer) + ra.nextInt(10)); } else { options[i] = answer.equals("不可解") ? String.format("%.2f", ra.nextInt(1000) + ra.nextDouble(10)) : String.format("%.2f", Double.parseDouble(answer) + ra.nextDouble(10)); } } for (int j = 0; j < i; j++) { if (options[j].equals(options[i])) { i--; break; } } if (options[i].equals(answer)) { i--; } } } } public String calculate(String question){ try { String expr = question.replaceAll(" ", ""); double result; if (!type.equals("高中")) { result = deal_calculate(expr); if (Double.isNaN(result) || Double.isInfinite(result)) { return "不可解"; } if (result == Math.floor(result)) { return String.valueOf((int) result); } else { return String.format("%.2f", result); } } else{ return deal_sen_calculate(expr); } } catch (Exception e) { return "不可解"; } } private double deal_calculate(String expr){ Stack numbers = new Stack<>(); Stack operators = new Stack<>(); expr=expr.replace("²", "^2"); for (int i = 0; i < expr.length(); i++) { char c = expr.charAt(i); if (Character.isDigit(c)) { StringBuilder temp = new StringBuilder(); while (i < expr.length() && (Character.isDigit(expr.charAt(i)) || expr.charAt(i) == '.')) { temp.append(expr.charAt(i++)); } i--; numbers.push(Double.parseDouble(temp.toString())); } else if (c == '(') { operators.push(c); } else if (c == ')') { while (operators.peek() != '(') { numbers.push(Deal_Operator(operators.pop(), numbers.pop(), numbers.pop())); } operators.pop(); } else if (isOperator(c)) { while (!operators.isEmpty() && hasPrecedence(c, operators.peek())) { numbers.push(Deal_Operator(operators.pop(), numbers.pop(), numbers.pop())); } operators.push(c); } else if (c == '√'){ i++; StringBuilder temp = new StringBuilder(); while (i < expr.length() && (Character.isDigit(expr.charAt(i)) || expr.charAt(i) == '.')) { temp.append(expr.charAt(i++)); } i--; numbers.push(Math.sqrt(Double.parseDouble(temp.toString()))); } } while (!operators.isEmpty()) { numbers.push(Deal_Operator(operators.pop(), numbers.pop(), numbers.pop())); } return numbers.pop(); } private String deal_sen_calculate(String m_expr){ try { String expr = m_expr.replaceAll(" ", ""); StringBuilder result = new StringBuilder(); int i = 0; while (i < expr.length()) { char c = expr.charAt(i); if (c == 's' || c == 'c' || c == 't') { StringBuilder trigFunc = new StringBuilder(); while (i < expr.length() && expr.charAt(i) != ')') { trigFunc.append(expr.charAt(i++)); } trigFunc.append(')'); // 添加右括号 String trigKey = trigFunc.toString(); String trigValue = trigValues.get(trigKey); if (trigValue != null) { result.append(trigValue); } } else if (isOperator(c) || c == '(' || c == ')') { result.append(c); } i++; } return String.format("%.2f",deal_calculate(Deal_Expression(result.toString()))); } catch (Exception e) { return "不可解"; } } private double Deal_Operator(char operator, double b, double a) { switch (operator) { case '+': return a + b; case '-': return a - b; case '*': return a * b; case '/': { if (b == 0) throw new ArithmeticException("除零错误"); return a / b; } case '^': return Math.pow(a, b); default: return 0; } } private boolean isOperator(char c) { return c == '+' || c == '-' || c == '*' || c == '/' || c == '^'; } //检验运算优先级,来决定先计算再压栈还是直接压栈 private boolean hasPrecedence(char op1, char op2) { if ( (op2 == '(' || op2 == ')') || ((op1 == '*' || op1 == '/') && (op2 == '+' || op2 == '-')) || (op1 == '^' && (op2 == '*' || op2 == '/' || op2 == '+' || op2 == '-'))) { return false; } return true; } private String Deal_Expression(String expr) { String simplified = expr.replace("+-","-"); simplified = simplified.replace("--","+"); return simplified; } }