三年级小学生计算大法(代码片段)

caizhenyi caizhenyi     2023-01-01     645

关键词:

211606301 蔡振翼 211605240 谢孟轩

一、预估与实际

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划
? Estimate ? 估计这个任务需要多少时间 5 5
Development 开发
? Analysis ? 需求分析 (包括学习新技术) 30 60
? Design Spec ? 生成设计文档 10 10
? Design Review ? 设计复审 5 10
? Coding Standard ? 代码规范 (为目前的开发制定合适的规范) 60 60
? Design ? 具体设计 120 150
? Coding ? 具体编码 600 1200
? Code Review ? 代码复审 10 20
? Test ? 测试(自我测试,修改代码,提交修改) 60 30
Reporting 报告
? Test Repor ? 测试报告 30 20
? Size Measurement ? 计算工作量 10 5
? Postmortem & Process Improvement Plan ? 事后总结, 并提出过程改进计划 20 10
合计: 1055 1570

二、需求分析

以下需求以人教版小学数学课本为准

一年级:
(1) 内容包含一百以内的加减法,大多数例题的答案也不存在超过一百的数字
(2)加减混合运算为两步计算试题
(3)不涉及负数。
二年级:
(1) 开始涉及万以内的加减法
(2) 乘法和除法都是表内乘除法
(3)除法中除数是9以内的,被除数为一百以内。
(4)出现三位参数的混合运算,两步计算试题
(5)含有余数的除法运算不涉及混合运算。
三年级:
(1)出现小数加减法,参数至多两位
(2)乘法开始出现两位数乘以两位数的乘法
(3)除法要求除数至多为两位数,被除数最多为三位
家长要求:
(1)运算符在2~4个
(2)可以加括号
(3)减法运算的结果不能有负数
(4)除法运算除数不能为0,不能有余数

(5) 至少存在两个不相同的运算符

经过分析,我认为,这个程序应当:
(1)对一二年级的代码进行完善补全
三年级应家长要求:
(1)小数部分的题目忽略不计
(2)计算参数在3~5个
(3)数字大小在1000以内,不存在负数
(4)舍弃含有余数的除法算数题

三、设计

1. 设计思路

说明你如何设计这个程序

设计思路①:穷举所有题目,将每道题目分别储存在String类型的数组中。按输入要求随机选择序号抽取题目按要求完成输出。这样避免了抽取重复题目等问题,但题目量巨大并不适合。
设计思路②:随机生成数字与符号利用逆波兰函数求得题目的答案写入文本。
设计思路③:随机本次抽取题目所需要的运算符的个数,随机抽取数字和符号进行运算,并把答案存入answer数组。抽取下一个符号,比较与上一个符号的运算等级判断是否需要加扩号重复如上不骤。一旦达到运算符要求结束题目写入文档。
技术分享图片

技术分享图片

2. 实现方案

写出具体实现的步骤

  • 准备工作:先在Github上创建仓库,克隆到本地,之后在仓库中创建文件夹,编写代码之后通过git传到github
  • 技术关键点:
    • 括号的选取
    • 除法无余数
    • 查重的实现
    • 有耐心看代码= =

四、编码

问题1:如何随机括号的位置(哪里需要括号,生成的括号是否合理,是否必要)
解决过程:从哪里需要括号,生成的括号是否合理,是否必要的角度进行思考,认为当乘除符号遇到加减符号时我们需要给加减的部分添加括号来保证运算顺利进行。这也是我们开始思考整体代码的开端。尽管在最后认真读了一遍例题才发现这一点并不必要。

问题2:如何公平随机生成多个运算符
解决过程:因为我们发现加法运算的数字在万以内,而乘法除法的数字在千以内,添加随机要求会导致题目中生成四个符号的概率并不平均。于是我们改小了加法和减法的范围,这个改变最明显的效果就是大量减少了“0÷(A+B)”这类题目的产生。没有办法达到绝对的公平只能尽力去靠近。

问题3:如何简化题目不重复
解决过程:解决这个问题的第一个想法是思路①,穷举所有题目进行抽取。之后我们通过百度查找各种解决“查重问题”方法。例如利用hashmap的映射。并不是看的很懂,但从中找到了解决问题的灵感。存储题目中的参数和答案到list中通过list.contains()方法进行查重。玩过24点的只到或许这并不是一个特别完美的方法,但这个方法从一方面上杜绝了这一现象,将错误查重的概率减到了很小。

问题4:如何解决除法方法无余数的运算
解决过程:最初我们采取逆向思维,随机除数和商相乘得到被除数来输出题目保证得到题目和答案不存在余数,解决了当我们随机除号在前时的问题。随机除号在我们已经得到的数字的后面,如何随机出适合的除数我们在挣扎过穷举被除数的所有因数时,得到Q群里一个同学提供的方法。随机除数,得到的余数用被除数减去它形成新的表达式解决了问题。

问题5:分工
解决过程:队友专门负责编写输入以及查重方面的代码,对其进行调试,而我负责运算方面。运算方面的代码对我来说有点颇困难,在她完成她的代码之后,我们互相讨论运算代码中除法的难点,一起解决了它。

1. 调试日志

记录编码调试的日志,请记录下开发过程中的 debug 历程

  • 在二年级除法运算中,因为需要保留上一次的要求,所以导致这次的余数不好解决
    解决方案:用一个数组存余数,在题数的for循环下判断,如果是二年级的除法,就在这个答案的后面增加余数
  • 三年级除法运算的括号问题
    解决方案:先规定运算符的优先级后,随机抽取运算符,这个运算符比上个运算符优先级弱的话,在上个运算符的前后加上括号
  • 三年级除法要求没余数
    解决方案:随机一个除数,将被除数与它相模,如果有余数则将被除数减去余数

2. 关键代码

请展示一段程序的关键代码,并解释代码的作用

以下代码是运算的代码,包括调用运算方法以及运算方法的代码:

//加法
private static void add(int i,StringBuffer word,int[] answer, int grade,int[] sub, int m) 
    // TODO 自动生成的方法存根
    if(grade==1) 
        num1 = (int) (Math.random()*(answer[i]-1));
        sub[m]=num1;
    else 
        num1 = (int) (Math.random()*99);
        sub[m]=num1;
    
    word.insert(word.length()," + "+num1);
    answer[i] = answer[i]+num1;

//减法
private static void sub(int i,StringBuffer word, int[] answer,int[] sub, int m) 
    // TODO 自动生成的方法存根
    num1 = (int) (Math.random()*(answer[i]-1));
    sub[m]=num1;
    word.insert(word.length(),"-"+num1);
    answer[i] = answer[i]-num1;

//乘法
private static void mul(int i,StringBuffer word, int[] answer, int grade,int[] sub, int m)
    // TODO 自动生成的方法存根
    if(grade==2) 
        num1 = (int) (Math.random()*9);
        sub[m]=num1;
    
    else 
        num1 = (int) (Math.random()*99);
        sub[m]=num1;
    
    word.insert(word.length(), "x"+num1);
    answer[i]= answer[i]*num1;

//除法
private static String div(int i,int j,int f, StringBuffer word, int[] answer,int grade,int[] sub, int m, int[] remb, int k) 
    // TODO 自动生成的方法存
    if(grade==2) 
        num1 = 1+(int)(Math.random()*9);
        rem=answer[i]%num1;
        remb[k] = rem;
        sub[m]=num1;
        word.insert(word.length(),"÷"+num1);
        answer[i]=answer[i]/num1;
    
    else
        test = 1+(int)(Math.random()*2);
        if(answer[i]==0 && f-j<=2) return "false";
        if((test==2 || answer[i]==0) && (f-j>2)) 
            
            num1 = 1+(int)(Math.random()*(answer[i]-1));  //除数
            if(answer[i]>99) num1 = 1+(int)(Math.random()*99);
            rem=answer[i]%num1; 
            sub[m]=num1;
            
            if(rem>0) word.insert(0, "(");
                word.insert(word.length(), "-"+rem+") ÷"+num1);
                answer[i]=(answer[i]-rem)/num1;
            else 
                word.insert(word.length(),"÷"+num1);
                answer[i]=answer[i]/num1;
            return "j++";
        
        
            num1 = (int)(Math.random()*((1000/answer[i])+1));  //被除数
            sub[m]=num1*answer[i];m++;
            word.insert(0,(num1*answer[i])+"÷");
            answer[i] = num1;
        return "true";



    return null;




private static void operation(int n, int grade)  
    // TODO 自动生成的方法存根
    //str数组储存了运算符的等级和符号;answer数组包含式子答案;word数组储存题目;f是随机运算符的个数;num是随机的第一个数;g是选择第g个运算符;i是第i道题;j是当前符号数量
    int k=0;//设置等级
    int[] str= 0,0,1,1; // 0为+-,1为*/
    int[] answer = new int[n]; //存答案的数组
    int[] sub = new int[6];//存数字的数组
    int[] remb = new int[n];
    
    
    File file = new File("out.txt"); 
    try 
        p = new PrintWriter(new FileOutputStream(file.getAbsolutePath()));
        out = new FileOutputStream(file);
        id = new StringBuffer("");
        
        for(int i=0;i<n;i++) //出n道题目的循环
            int m=0; //存数字个数
            int level=1;
            if(grade==1) 
                g = (int)(Math.random()*(str.length-2));
                answer[i]=(int) (Math.random()*99);
                sub[m]=answer[i];m++;
                word= new StringBuffer(answer[i]+"");
                if(g==1) 
                    add(i,word,answer,g,sub,m);m++;
                
                else 
                    sub(i,word, answer,sub,m);m++;
                
                
            
            else if(grade==2) 
                g = (str.length-2)+(int)(Math.random()*str.length);
                if(g==3) 
                    answer[i]=(int) (Math.random()*99);
                    sub[m]=answer[i];m++;
                    word= new StringBuffer(answer[i]+"");
                    div(i,0,0,word, answer,grade,sub,m,remb,k);
                    m++;k++;
                
                else 
                    answer[i]=(int) (Math.random()*9);  
                    sub[m]=answer[i];m++;   
                    word= new StringBuffer(answer[i]+"");
                    mul(i,word, answer,grade,sub,m);
                    m++;
                
            
            else //三年级
                f = 2+(int) (Math.random()*3); //f:随机抽取运算符的个数
                g = (int)(Math.random()*(str.length-1));//第一个运算符
                answer[i]= (int) (Math.random()*99);
                sub[m]=answer[i];m++;
                word= new StringBuffer(answer[i]+"");
                final int g1=g;
                for(int j=0;j<f;j++) 
                    if(level<str[g] && j>f-2 && j>=2)  break;//在需要加括号的情况下运算符不够用
                    if(level<str[g]) 
                        //加括号
                        word.insert(0, "(");
                        word.insert(word.length(), ")");
                        j++;
                    
                    level=str[g];
                     //随机选择符号
                    if(g==0)   
                        add(i,word, answer,g,sub,m);m++;
                    
                    else if(g==1) 
                    
                        sub(i,word, answer,sub,m);m++;
                        
                    else if(g==2) 
                        
                        if(div(i,j,f,word, answer,grade,sub,m,remb,k).equals("j++"))
                            j=j+2;
                        else if(div(i,j,f,word, answer,grade,sub,m,remb,k).equals("false")) 
                            i--;break;
                        
                        m++;k++;
                        
                    
                    else 
                        mul(i,word, answer,grade,sub,m);m++;
                    
                    g = (int)(Math.random()*(str.length));
                    if(answer[i]>=100) 
                    g = (int)(Math.random()*(str.length-1));
                    
                    while(g==g1 && j==0)
                    
                    g = (int)(Math.random()*(str.length));
                    if(answer[i]>=100) 
                    g = (int)(Math.random()*(str.length-1));
                    
                       
            
            word.insert(0, "("+(i+1)+")");
            if(grade==2 && g==3 && remb[k-1]!=0) 
            id.insert(id.length(), word+"="+answer[i]+"..."+remb[k-1]+"
");
            
            else 
                id.insert(id.length(), word+"="+answer[i]+"
");
            
            word.insert(word.length(),"
");
            System.out.println(word);
            System.out.println(answer[i]);
            p.write(word.toString());
            


        

        p.write("
");
        p.write(id.toString());
        p.close();
        out.close();
     catch (IOException e) 
        // TODO 自动生成的 catch 块
        e.printStackTrace();
     
    

3. 代码规范

请给出本次实验使用的代码规范:

  • 第一条:常量命名全部大写,单词键用下划线隔开,力求语义表达完整,不要嫌名字长。
  • 第二条:类型与中括号紧挨相连来定义数组。
  • 第三条:左小括号和字符之间不出现空格;同样的,有小括号和字符之间也不出现空格。详见第5条下面正例提示。
  • 第四条: if/for/while/switch/do等保留字与括号之间都必须加空格。
  • 第五条:采用4个空格缩进,禁止使用tab字符
    技术分享图片

五、测试

请思考并记录你认为必要的测试点,并记录测试用例与测试结果

测试用例 结果
java MathExam6301 -n 10 -grade 1 将1年级的加减法正确地输入到out.txt文件中
java MathExam6301 -n 10 -grade 2 将2年级的乘除法正确地输入到out.txt文件中
java MathExam6301 -n 10 -grade 3 将3年级的混合四则运算法正确地输入到out.txt文件中
java MathExam6301 -grade 1 -n 10 程序正常运行
java MathExam6301 输入的参数应为4个
java MathExam6301 -n as -grade sfas 输入的年级数与题数应为数字
java MathExam6301 1 1 查找不到-n或者-grade
java MathExam6301 -n 1 -grade 5 输入年级应在一到三年级
java MathExam6301 -n 1000000 -grade 1 输入题目数量应该在1~1000

六、总结

不得不说,这一次结对作业对我的帮助还是很大的。分工之后,双方有更多的时间沟通交流,在敲代码初期便把准备工作做好了;打代码中,不会的问题还可以互相交流,虽然我的问题真多,可是慢慢学之后我又进步了。
一度地敲代码,让我只想用呵呵两字。又能表示自己的吐槽之意,也表示我的开心想法。打不出来,一直盯着电脑,眼睛都快炸了,依旧 卖呆咯。但是,突破困难之后,舒服。。。。是真的舒服。
我还有很长的路要走,我一直在拖队友的后腿,不甘心,真的很不甘心。
最后,送上我和我队友的表情包哈!

技术分享图片





































mathexam小学一二年级计算题生成器v1.0(代码片段)

MathExam小学一二年级计算题生成器v1.0一、预估与实际PSP2.1PersonalSoftwareProcessStages预估耗时(分钟)实际耗时(分钟)Planning计划?Estimate?估计这个任务需要多少时间8801540Development开发?Analysis?需求分析(包括学习新技术)60100?DesignSpec?... 查看详情

myysqlcasewhen多个参数结果(代码片段)

--查看所有学生的姓名班级,如果班级为1表示一年级,2表示二年级,3表示三年级selects.StudentName,CASEWHENs.GradeId=1THEN'一年级'WHENs.GradeId=2THEN'二年级'WHENs.GradeId=3THEN'三年级'ELSE'其他'ENDfromstuden 查看详情

四则运算分析与设计(代码片段)

...是什么学科?A、数学B、语文C、英语D、其他 3、您教几年级的学生?A、一年级B、二年级C、三年级D、四年级E、五年级F、六年级 4、学生需要练习哪种类型的运算题?[多选题]A、简单算数题例如2+2-1=3B、带分数的四则运算C、四... 查看详情

pta7-19暴力小学(二年级篇)-求出2个三位数(10分)(代码片段)

小博是新城小学二年级学生,这孩子人很老实,数学、语文成绩也是中等水平。不过一旦坐在电脑前,写起代码来,则有些霸气侧漏,尤其擅长各种暴力方法。本题就是数学莫老师的题目之一,请你和小博一起暴力求解吧。输入... 查看详情

统计分数(代码片段)

题目描述这次桐桐要统计的是全市七年级学生的期末成绩,一共统计五个科目:语文、数学、英语、政治和历史。仍然是计算所有学生的五科总成绩,并按照由高到低的顺序将总成绩输出,但是全市七年级学生的总数可能达到200... 查看详情

小学生二年级四则运算2.0(代码片段)

在原有基础之上,希望加上分数的四则运算。此次编程实现功能:30道四则运算题的编写(不重复编写)                支持整型四则运算,还有分数四则运算  &nbs... 查看详情

小学一二年级随机四则运算(代码片段)

小学一二年级随机四则运算一、预估与实际PSP2.1PersonalSoftwareProcessStages预估耗时(分钟)实际耗时(分钟)Planning计划?Estimate?估计这个任务需要多少时间14401085Development开发?Analysis?需求分析(包括学习新技术)120100?DesignSpec?生成设计... 查看详情

小学二年级三十道四则运算题目。

代码:#include <stdio.h>#include <string.h>#include <stdlib.h>#include <time.h>int main(int argc, char **argv)    int& 查看详情

案例十一:查询学生表的学号,姓名和所在年级(代码片段)

SELECTstudentnoAS‘学号‘,studentnameAS‘姓名‘,gradenameAS‘年级‘FROMstudentASsLEFTJOINgradeASgONs.gradeid=g.gradeid; 查看详情

小学三年级数学题!用数字1到8组成两个三位数使其和为1000

...两个三位数里面的数字不能重复。问能写几组?用小学三年级的解题思路还真没想到。只好用笨方法跑个小程序了。L=list(range(1,9))#print(L)s=""S=[]forlinL:forl1inL:forl2inL:ifstr(l)<>str(l1)andstr(l)<>str(l2)andstr(l1)<> 查看详情

编程练习(代码片段)

#!/bin/bashecho"小学生测验面向小学1~2年级学生,随机选择两个整数进行四则运算,要求学生解答。功能要求:(1)电脑随机出10道题,每题10分,程序结束时显示学生得分;(2)确保算式没有超出1~2年级的水平,只允许进行100... 查看详情

设计四则运算包含真分数的小学二年级运算(代码片段)

本次我在上次的四则运算的基础上加上了真分数运算,在之前的基础上改变一下运算代码代码如下:#include<stdio.h>#include<Windows.h>#include<time.h>voidmain()inta,b,c,d,i,m,n;floatp,q;srand(unsigned(time(NULL)));for(i=0;i<30;i++) 查看详情

小学二年级三十道四则运算题目-扩展运算,添加指定题目数量和支持真分数运算

代码:#include<stdio.h> #include<Windows.h> #include<time.h> voidmain()      inta,b,c,d,i,m,n;     floatp,q;  查看详情

关于运用c语言自动生成三十道小学二年级四则运算

#include<stdio.h>#include<stdlib.h>#include<time.h>intmain()  inti=0;  srand((unsigned)time(NULL));  while(i<30)       inta=rand()%100;    intb=rand()%100;    intj;   j=rand()%4 查看详情

第一次软件工程作业(代码片段)

...喜欢计算机这个专业吗?是,第一次接触计算机是小学三年级的时候,当时就被计算机的科技感所吸引。-你现在后悔选择了这个专业吗?不后悔,我觉得计算机是一门很好的专业,就业前景非常好,我也很感兴趣。你认为你现... 查看详情

个人项目1:一个能生成小学二年级四则运算题目的“软件”(代码片段)

做这个程序,用了差不多半个小时。从开始的思路到语句的实践,之间也出现了一些语法的错误,最后也得到了修正。由于学习的语言种类有限(c#刚刚开始学,大一时学习过c语言),在这里选择用C语言编写这个程序,环境是vs... 查看详情

小学三年级的学生学过哪些有关食物的单词

有关食物的单词:juice、rice、bread、milk、fish。一、juice1、含义:n.果汁;肉汁;消化液;汽油;精力。vt.挤出汁来;使有活力。2、用法:juice的基本意思是“汁,液”,一般指的是水果、蔬菜、肉等的汁或液。可用作不可数名词,也... 查看详情

习题练习(代码片段)

1.查询所有学生记录,包含年级名称2.查询S1年级下的学生记录  packagecom.myschool.dao;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLEx 查看详情