pull/2/head
陈映江 5 months ago
parent 5f5dc962c7
commit ac7c3053f9

@ -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);
}
}

@ -0,0 +1,90 @@
package mathlearning.service.MultipleChoiceGenerator;
import mathlearning.model.User;
import mathlearning.service.QuestionGenerator.*;
import java.util.*;
public class MultipleChoiceGenerator {
private static QuestionGenerator QuestionGenerator = new PrimaryGenerator();
String[] QuestionList ;
String[] AnswerList ;
String[] ChoiceList ;
MultipleChoiceGenerator(int count, User nowUser){// 如此声明MultipleChoiceGenerator实例,再调用下面三个接口
this.QuestionList = new String[count];
this.ChoiceList = new String[count];
this.QuestionList = SetQuestionList(count, nowUser);
SetChoiceList();
}
public String[] GetQuestionList(){
return this.QuestionList;
}
public String[] GetChoiceList(){
return this.ChoiceList;
}
public String[] GetAnswerList(){
return this.AnswerList;
}
private void SetChoiceList(){
for(int i = 0 ; i < this.AnswerList.length ; i++){
Random random = new Random();
String[] choices = new String[4];
double correctChoice = Double.parseDouble(this.AnswerList[i]);
int position = random.nextInt(4);
choices[position] = String.format("%.2f", correctChoice);
for(int j = 0 ; j < 4 ; j++){
if(j != position){
double choice = correctChoice;
double offset = random.nextInt(41) - 20;
choice += offset;
choices[j] = String.format("%.2f", choice);
}
}
this.ChoiceList[i] = String.join("\n", choices);
}
}
private String[] SetQuestionList(int count, User nowUser){
String[] Questions= new String[count];
if(nowUser.getType().equals("小学") ) {
QuestionGenerator = new PrimaryGenerator();
}
else if( nowUser.getType().equals("初中") ) {
QuestionGenerator = new middleGenerator();
}
else if( nowUser.getType().equals("高中") ) {
QuestionGenerator = new highGenerator();
}
List<String> questions = new ArrayList<>();
Set<String> generatedQuestions = new HashSet<>();
for (int i = 0; i < count; i++) {
String question;
do {
question = QuestionGenerator.generateQuestion();
} while ( generatedQuestions.contains(question ));
generatedQuestions.add(question);
questions.add(question);
}
for(int i = 0 ; i< count ; i++){
Questions[i] = questions.get(i);
}
this.AnswerList = new String[count];
for(int i = 0 ; i< count ; i++){
ComputingUnit computingUnit = new ComputingUnit(Questions[i]);
this.AnswerList[i] = computingUnit.getAnswer();
}
return Questions;
}
}

@ -0,0 +1,37 @@
package mathlearning.service.MultipleChoiceGenerator;
import mathlearning.model.User;
public class MultipleChoiceGeneratorTest {
public static void main(String[] args) {
// 创建一个模拟用户
User testUser = new User();
testUser.setType("小学"); // 可以分别测试"小学"、"初中"、"高中"
// 测试生成10道题目
int questionCount = 10;
MultipleChoiceGenerator generator = new MultipleChoiceGenerator(questionCount, testUser);
// 获取生成的题目、答案和选项
String[] questions = generator.GetQuestionList();
String[] answers = generator.GetAnswerList();
String[] choices = generator.GetChoiceList();
// 输出测试结果
System.out.println("=== 数学题目生成测试 ===");
System.out.println("用户类型: " + testUser.getType());
System.out.println("生成题目数量: " + questionCount);
System.out.println();
for (int i = 0; i < questions.length; i++) {
System.out.println("题目 " + (i + 1) + ": " + questions[i]);
System.out.println("答案: " + answers[i]);
System.out.println("选项:");
String[] choiceArray = choices[i].split("\n");
for (int j = 0; j < choiceArray.length; j++) {
System.out.println(" " + (char)('A' + j) + ". " + choiceArray[j]);
}
System.out.println("----------------------------------------");
}
}
}

@ -0,0 +1,22 @@
package mathlearning.service.QuestionGenerator;
public class PrimaryGenerator extends QuestionGenerator{
public PrimaryGenerator() {
super("小学");
}
@Override
public String generateQuestion() {
int operandCount = random.nextInt(4) + 2;
// 生成操作数
int[] operands = new int[operandCount];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(100) + 1; // 1-100
}
String question = preForOper(operands);
return addParen(question);
}
}

@ -0,0 +1,142 @@
package mathlearning.service.QuestionGenerator;
import java.util.Random;
public abstract class QuestionGenerator{
protected Random random = new Random();
public abstract String generateQuestion() ;
protected String type;
public String getType() {
return type;
}
QuestionGenerator() {
type = "无";
}
QuestionGenerator(String Type) {
type = Type;
}
protected String preForOper(int[] operands) {
StringBuilder question = new StringBuilder();
String[] operators = {"+", "-", "×", "÷"};
question.append(operands[0]);
for (int i = 1; i < operands.length; i++) {
String op = operators[ random.nextInt (operators.length)];
question.append(" ").append(op).append(" ").append(operands[i]);
}
return question.toString();
}
protected boolean Check_num(String expression) {
if(!(expression.equals("+") || expression.equals("-") || expression.equals("×") || expression.equals("÷"))) {
return true;
}
else{
return false;
}
}
protected String addParen(String expression) {
String[] parts = expression.split(" ");
StringBuilder result = new StringBuilder();
boolean r_paren_needed = false;
for (int i = 0; i < parts.length; i++) {
if(Check_num ( parts [i]) ) {
if( !r_paren_needed ) {
if(i <= parts.length -3 )
{
if( random.nextBoolean() )
{ result.append("(");r_paren_needed = true;}
}
result.append(parts[i]);
} else {
result.append( parts [i]);
if( !random.nextBoolean()) {
result.append(")");r_paren_needed = false;
}
}
} else {
result.append( parts [i] );
}
if( i < parts.length -1 ) {
result.append(" ");
}
}
if( r_paren_needed ){
result.append(")");r_paren_needed = false;
}
return result.toString();
}
protected String add_squs(String expression) {
String[] parts = expression.split(" ");
StringBuilder result = new StringBuilder();
boolean has_squs = false;
for (int i = 0; i < parts.length; i++) {
if( Check_num( parts [i] )) {
double Thres = 0.3;
if( !has_squs){
Thres = 0.7;
}
if ( random.nextDouble() < Thres ||(i == parts.length -1 && !has_squs)) {
if ( random.nextBoolean() ) {
result.append(parts[i]);
result.append("²");
has_squs = true;
} else {
result.append("√");
result.append(parts[i]);
has_squs = true;
}
} else {
result.append(parts[i]);
}
} else {
result.append(parts[i]);
}
if( i < parts.length -1 ) {
result.append(" ");
}
}
return result.toString();
}
protected String add_sins(String expression) {
String[] parts = expression.split(" ");
StringBuilder result = new StringBuilder();
String[] functions = {"sin", "cos", "tan"};
boolean has_func = false;
for (int i = 0; i < parts.length; i++) {
double Thres = 0.4;
if(!has_func){Thres = 0.8;}
if(Check_num(parts[i]))
{
if ( random.nextDouble() < Thres ||(i == parts.length-1 && !has_func) ) {
String func = functions[random.nextInt(functions.length)];
result.append(func).append("(").append(parts[i]).append(")");
} else {
result.append(parts[i]);
}
} else {
result.append(parts[i]);
}
if( i < parts.length-1 ) {
result.append(" ");
}
}
return result.toString();
}
}

@ -0,0 +1,24 @@
package mathlearning.service.QuestionGenerator;
public class highGenerator extends QuestionGenerator{
public highGenerator() {
super("高中");
}
@Override
public String generateQuestion() {
int operandCount = random.nextInt(4) + 2;
// 生成操作数
int[] operands = new int[ operandCount ];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(100) + 1; // 1-100
}
String question = preForOper( operands );
question = add_squs( question );
question = add_sins( question );
return addParen( question );
}
}

@ -0,0 +1,23 @@
package mathlearning.service.QuestionGenerator;
public class middleGenerator extends QuestionGenerator{
public middleGenerator() {
super("初中");
}
@Override
public String generateQuestion() {
int operandCount = random.nextInt(4) + 2;
// 生成操作数
int[] operands = new int [ operandCount ];
for (int i = 0; i < operandCount; i++) {
operands[i] = random.nextInt(100) + 1; // 1-100
}
String question = preForOper(operands);
question = add_squs(question);
return addParen(question);
}
}
Loading…
Cancel
Save