2018103002-小学四则运算练习软件项目报告
代码地址:https://git.coding.net/SaraPJQ/szys.git彭佳琦
-
需求分析
为了提高教师的工作效率,减轻家长课后辅导的负担,利用JAVA语言开发一款应用于小学生的四则运算练习出题软件。
基本要求:
程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。
每个练习题至少要包含2种运算符。不得出现负数与非整数。
练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。
-
功能设计
- 基本功能:
输入参数n(n为正整数)可随机产生n道运算数字在 0 - 100 内的混合运算题
每道题至少出现2种运算符,且运算符个数为3-5个
将学号和n道练习题及其对应的正确答案输出到文件“result.txt”中
2.扩展功能:
支持括号运算式的出题与求解正确答案,括号数应大于2对,且不超过运算符的个数
支持真分数的出题与运算(只需加减法),保证计算过程中与结果都为真分数
-
设计实现
通过两个类文件来实现,分别为Main主类、Lib辅助类。Main负责接收并判断参数n,将符合要求的运算式及其结果输出到result.txt中。Lib负责实现带括号的整数计算和真分数的加减运算,zhengshu()用于实现带括号的四则整数运算;zhenfenshu()用于实现真分数的加减运算,前两者的实现采用边生成边计算的方法;yuefen()求最大公约数,被zhenfenshu()调用实现约分以保证运算式中均为真分数。
-
算法详解
- 整数计算
arith、sum分别用于保存运算后的式子和结果,fh、fh1分别为前后两次运算的运算符,x、y为0-100内的随机整数。
在进行运算时,并根据运算符号的情况对sum进行相应的计算,并将arith更新。当运算符为减法时,若sum<0需重新生成随机数。当运算符为乘法时,需判断前后两个运算符的优先级,若前一个运算符为加或减,则arith="("+arith+")"+operate[fh1]+y1;。当运算符为除法时,先判断除数是否为0和是否有余数,若是重新生成随机数;之后再判断前后两个运算符的优先级。每步计算完成后fh=fh1来更新运算符。
2.真分数计算
首先,随机生成两个分数判断其分子分母的大小(若分子大于等于分母需重新生成分母)并调用yuefen()对真分数进行化简得到真分数。其次,计算这两个分数,若相加通分后需先判断新分子和新分母大小,再约分;若相减通分后需先判断新分子、新分母大小及新分子是否小于0,再约分。记录新分数的值和运算式。最后再生成一分数与上步得到的新分数进行计算,重复上述步骤。
-
测试运行
程序要求输入参数n的数值为0-1000之间。
输入1050,由于n的数值超过其范围,则输出“输入失败,请输入正整数!”
输入150,会生成150道运算式并将其打印输出在result.txt中
-
代码
实现整数计算部分代码
for(int j=1;j<f;j++){//随机生成余下的运算符
int fh1 = random.nextInt(4);//随机生成下一个运算符号
int y1 = random.nextInt(100);//随机生成0-100内的整数y1
if(operate[fh1]=='+'){
sum=sum+y1;
arith=arith+""+operate[fh1]+""+y1;
}
if(operate[fh1]=='-'){
while(sum-y1<0)
{
y1=random.nextInt(101);
}
sum=sum+y1;
arith=arith+""+operate[fh1]+""+y1;
}
if(operate[fh1]=='*'){//若下一个运算符号为乘号,判断前后两个运算符的优先级
if(operate[fh]=='+'||operate[fh]=='-')
{
arith="("+arith+")"+operate[fh1]+y1;
}
else
{
arith=arith+""+operate[fh1]+""+y1;
}
sum=sum*y1;
}
if(operate[fh1]=='÷'){//若下一个运算符号为除号,判断前后两个运算符的优先级
while (y1==0||sum%y1!=0) {
y1=random.nextInt(99) + 1;
}
if(operate[fh]=='+'||operate[fh]=='-')
{
arith="("+arith+")"+operate[fh1]+y1;
}
else
{
arith=arith+""+operate[fh1]+""+y1;
}
sum=sum/y1;
}
fh=fh1;//更新运算符
}
System.out.println(arith+"="+sum);//输出运算式及结果
真分数计算部分代码
for (int i = 0; i < n; i++) {
int type = random.nextInt(2);
int fz1 = random.nextInt(10) + 1;// 分子1
int fm1 = random.nextInt(15) + 1;// 分母1
if (fz1 > fm1)//分子大于分母,重新生成分母
fm1 = random.nextInt(10) + 1;
int fz2 = random.nextInt(10) + 1;// 分子2
int fm2 = random.nextInt(10) + 1;// 分母2
if (fz2 > fm2)
fm2 = random.nextInt(15) + 1;
int yffz1 = fz1 / yuefen(fz1, fm1);//得到真分数
int yffm1 = fm1 / yuefen(fz1, fm1);
if (operate[type] == '+') {
fz1 = fz1 * fm2 + fz2 * fm1;//通分得到新分子
int fm = fm1 * fm2;//新分母
if (fz1 > fm) {//新分子大于新分母,重新生成随机数
fz1 = random.nextInt(6) + 1;
fm1 = random.nextInt(8) + 1;
}
fz1 = fz1 / yuefen(fz1, fm);//约分成真分数
fm1 = fm / yuefen(fz1, fm);
}
if (operate[type] == '-') {
fz1 = fz1 * fm2 - fz2 * fm1;
int fm = fm1 * fm2;
if (fz1 > fm || fz1 < 0) {//新分子大于新分母或新分子小于0
fz1 = random.nextInt(10) + 1;
fm1 = random.nextInt(15) + 1;
}
fz1 = fz1 / yuefen(fz1, fm);
fm1 = fm / yuefen(fz1, fm);
}
System.out.print(yffz1 + "/" + yffm1 + operate[type] + fz2 + "/" + fm2);
-
总结
通过此次项目,我获得了许多感慨和体会。由于自身编程能力较弱,我一直害怕去编程,虽然此次项目的完成不是很顺利,我深刻地认识到自己的不足,也希望自己日后努力学习编程语言提高编程能力。除此之外,在阅读《构建之法》时,我一直对PSP流程抱有怀疑的态度,直到这次实践我才明白PSP的必要性。在刚开始的设计实现时,我学习了调度场算法并想利用它来解决问题,直到动手实现时才发现,运用java语言实现栈的算法并不是我想象的那么容易,于是我便改用了其它方法,但我还是想用调度场算法来实现,接下来我会用课余时间争取学习并解决这个问题。
-
PSP