小学生题目生成器

这次写了一个小学生作业生成器,感觉自己才是个小学生

需求分析

[√] 控制生成题目的个数。
[√] 控制题目中数值(自然数、真分数和真分数分母)的范围。
[√] 生成的题目中如果存在形如e1 ÷ e2的子表达式,那么其结果应是真分数。
[√] 每道题目中出现的运算符个数不超过3个。
[x] 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。
[√] 在生成题目的同时,计算出所有题目的答案,并存入执行程序的当前目录下的Answers.txt文件。
[√] 程序应能支持一万道题目的生成。
[x] 程序支持对给定的题目文件和答案文件,判定答案中的对错并进行数量统计,并会输出所有题目中重复的题目。

功能设计

生成表达式
计算结果
分数转换
判断对错
生成文件

设计实现

根据功能整个项目由5个类构成:
  CreateExpression负责生成表达式,其中是根据随机数生成算符个数,根据算符个数生成算数个数,根据随机数生成分数或整数,以及通过随机数生成括号及括号位置。
  CalculateExpression负责计算表达式,通过调用js的eval方法实现直接计算。
  resultToFraction负责将结果转化为分数,通过遍历数值范围平方找到结果,并返回。
  JudgeAnswer负责判断对错,将计算结果与输入结果传入judge方法判断并显示。
  Study是程序的主方法,其中有文件的读写,对表达式和结果的判断,控制范围输入和题目个数输入。


代码说明

1.生成表达式

public class CreateExpression {
    static final char[] operator = { '+', '-', '*', '/' };

    public static String createExpression(int range) {
        int num = new Random().nextInt(2) + 1;//算符个数
        String[] number = new String[num + 1];
        char[] op = new char[num];
        String expression = "";
        int length = number.length;
        for (int i = 0; i < num; i++) {
            op[i] = operator[(int) (Math.random() * 4)];//生成算符
        }
        for (int i = 0; i < num + 1; i++) {//生成算数
            if (Math.random() > 0.5)//通过随机数生成
                number[i] = (int) (Math.random() * range) + "";//整数
            else
                number[i] = (int) (Math.random() * range) + "/"
                        + (int) ((Math.random() * range) + 1) + "";//分数
        }
        int flag = (int) (Math.random() * 4);//括号生成
        switch (flag) {
        case 0:
        case 1:
            for (int i = 0; i < length; i++) {
                expression += number[i];
                if (i <= length - 2)
                    if (op[i] != '/'
                            || number[i + 1].indexOf("/") != -1
                            || (op[i] == '/' && Integer.parseInt(number[i + 1]) != 0))//判断除数非0
                        expression += op[i];
                    else {
                        expression = "";
                        return null;
                    }
            }
            break;
        case 2:
            if (length > 2) {
                for (int i = 0; i < length; i++) {
                    if (i == 0)
                        expression += "(";
                    expression += number[i];
                    if (i == 1)
                        expression += ")";
                    if (i <= length - 2)
                        if (op[i] != '/'
                                || number[i + 1].indexOf("/") != -1
                                || (op[i] == '/' && Integer
                                        .parseInt(number[i + 1]) != 0))
                            expression += op[i];
                        else {
                            expression = "";
                            return null;
                        }
                }
                break;
            } else {
                for (int i = 0; i < length; i++) {
                    expression += number[i];
                    if (i <= length - 2)
                        if (op[i] != '/'
                                || number[i + 1].indexOf("/") != -1
                                || (op[i] == '/' && Integer
                                        .parseInt(number[i + 1]) != 0))
                            expression += op[i];
                        else {
                            expression = "";
                            return null;
                        }
                }
                break;
            }
        case 3:
        case 4:
            if (length > 2) {
                for (int i = 0; i < length; i++) {
                    if (i == 1)
                        expression += "(";
                    expression += number[i];
                    if (i <= length - 2)
                        if (op[i] != '/'
                                || number[i + 1].indexOf("/") != -1
                                || (op[i] == '/' && Integer
                                        .parseInt(number[i + 1]) != 0))
                            expression += op[i];
                        else {
                            expression = "";
                            return null;
                        }
                    if (i == 2)
                        expression += ")";
                }
                break;
            } else {
                for (int i = 0; i < length; i++) {
                    expression += number[i];
                    if (i <= length - 2)
                        if (op[i] != '/'
                                || number[i + 1].indexOf("/") != -1
                                || (op[i] == '/' && Integer
                                        .parseInt(number[i + 1]) != 0))
                            expression += op[i];
                        else {
                            expression = "";
                            return null;
                        }
                }
            }
        }
        return expression;
    }

2.计算表达式

public Object calculate(String expression) {
        ScriptEngineManager manager = new ScriptEngineManager();
        ScriptEngine engine = manager.getEngineByName("js");//调用js引擎
        Object result = null;
        try {
            result = engine.eval(expression);//调用eval方法
            if (Double.parseDouble(String.valueOf(result)) < 0) {
                return null;
            }
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        return result;
    }

3.分数转换

public String convert(String res, int range) {
        String result = null;
        String[] array = new String[2];
        array = res.split("\\.");
        float x, y;
        int ext = 0;
        Integer b1;
        int a = Integer.parseInt(array[0]);// 获取整数部分
        String str_b = String.valueOf(array[1]);// 获取小数部分且判断0个数
        for (int i = 0; i < str_b.length() && str_b.charAt(i) == '0'; i++) {
            ext = i + 1;
        }
        int b = Integer.parseInt(str_b);
        if (b == 0) {
            result = a + "";
        } else {
            b1 = b;
            x = (float) (b / (Math.pow(10, b1.toString().length() + ext)));//将小数点后转化成float型
            for (int i = 1; i <= range * range; i++) {//遍历
                for (int j = i; j <= range * range; j++) {
                    y = (float) i / (float) j;
                    if (y == x)
                        if (a == 0) {
                            result = i + "/" + j + "";
                            return result;
                        } else {
                            result = a + "'" + i + "/" + j + "";
                            return result;
                        }
                    else
                        continue;
                }
            }
        }
        return result;
    }

4.判断结果

public void judge(String[] s1, String[] s2) {
        int correctnum = 0;
        int length = s1.length;
        int[] correct = new int[length];
        int[] wrong = new int[length];
        for (int i = 0; i < length; i++) {
            if (s1[i].equals(s2[i])) {
                correct[correctnum] = i + 1;//记录正确结果题目号
                correctnum++;//记录正确结果个数
            } else {
                wrong[i - correctnum] = i + 1;//错误结果题目号
            }
        }
        //打印结果
        System.out.print("Correct:" + correctnum);
        for (int i = 0; i < correctnum; i++) {
            if (i == 0)
                System.out.print("( ");
            if (i < correctnum - 1)
                System.out.print(correct[i] + " , ");
            else
                System.out.print(correct[i] + " )");
        }
        System.out.print("Wrong:" + (length - correctnum));
        for (int i = 0; i < length - correctnum; i++) {
            if (i == 0)
                System.out.print("( ");
            if (i < length - correctnum - 1)
                System.out.print(wrong[i] + " , ");
            else
                System.out.println(wrong[i] + " )");
        }
    }

5.主方法

public static void start() throws IOException {

        Scanner sc = new Scanner(System.in);
        int loopnum = 0, range;

        System.out.println("输入题目文件名称");
        File questionFile = new File(sc.next());
        while (questionFile.exists()) {
            System.out.println("文件已存在,请重新输入");
            questionFile = new File(sc.next());
        }
        FileWriter q_writer = new FileWriter(questionFile, true);

        System.out.println("输入文件答案名称");
        File answerFile = new File(sc.next());
        while (answerFile.exists()) {
            System.out.println("文件已存在,请重新输入");
            answerFile = new File(sc.next());
        }
        FileWriter a_writer = new FileWriter(answerFile, true);
        System.out.println("输入题目个数");
        loopnum = sc.nextInt();
        System.out.println("输入数值范围");
        range = sc.nextInt();
        String[] i_anwser = new String[loopnum];
        String[] q_anwser = new String[loopnum];
        //开始生成
        for (int i = 0; i < loopnum; i++) {
            CreateExpression cte = new CreateExpression();
            String expression = cte.createExpression(range);
            Object result = null;
            //判断表达式是否可用
            if (expression != null && !expression.equals(null)) {
                CalculateExpression cce = new CalculateExpression();
                result = cce.calculate(expression);
                //判断结果是否可用
                if (result == null || result.toString().equals("Infinity") || result.toString().equals("NaN")) {
                    i--;
                    continue;
                } else {
                    resultToFraction rtf = new resultToFraction();
                    String n_result = rtf.convert(String.valueOf(Float.parseFloat(result.toString())), range);//将结果转化成有限小数
                    System.out.println(expression);
                    q_writer.write(i + "." + expression);
                    a_writer.write(i + "." + n_result);
                    q_anwser[i] = n_result;
                }
            } else {
                i--;
            }
        }
        System.out.println("输入答案");
        for (int i = 0; i < loopnum; i++) {
            i_anwser[i] = sc.next();
        }
        JudgeAnswer jda = new JudgeAnswer();
        jda.judge(q_anwser, i_anwser);
    }

测试运行

1.控制台

控制台
2.生成文件

生成文件


PSP

PSP2.1Personal Software Process StagesTime Senior StudentTime
Planning计划2020
Estimate估计这个任务需要多少时间55
Development开发500700
Analysis需求分析 (包括学习新技术)3010
Design Spec生成设计文档51
Design Review设计复审21
Coding Standard代码规范11
Design具体设计2030
Coding具体编码400470
Code Review代码复审108
Test测试(自我测试,修改代码,提交修改)60150
Reporting报告2060
测试报告1245
计算工作量35
并提出过程改进计划810

小结
那个判重算法真的不太懂。。
要把小学生逼疯就要先把自己逼疯。
不过做你的一万道题去吧:)


项目地址>>

转载于:https://www.cnblogs.com/Symumi/p/7552019.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值