2018103002-小学四则运算练习软件项目报告

代码地址:https://git.coding.net/SaraPJQ/szys.git彭佳琦

  • 需求分析

为了提高教师的工作效率,减轻家长课后辅导的负担,利用JAVA语言开发一款应用于小学生的四则运算练习出题软件。

基本要求:

程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号+-*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。

每个练习题至少要包含2种运算符。不得出现负数与非整数。

练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。

  • 功能设计

  1. 基本功能:

输入参数nn为正整数随机产生n道运算数字 0 - 100 的混合运算

题至少出现2种运算符,且运算符个数为3-5个

将学号n道练习题及其对应的正确答案输出到文件“result.txt”中

     2.扩展功能:

支持括号运算式出题与求解正确答案,括号数大于2对且不超过运算符的个数

支持真分数的出题与运算(只需加减法),保证计算过程中与结果都为真分数

  • 设计实现

    通过两个类文件来实现,分别为Main主类、Lib辅助类。Main负责接收并判断参数n,将符合要求的运算式及其结果输出到result.txt中。Lib负责实现带括号的整数计算和真分数的加减运算,zhengshu()用于实现带括号的四则整数运算;zhenfenshu()用于实现真分数的加减运算,前两者的实现采用边生成边计算的方法;yuefen()求最大公约数,被zhenfenshu()调用实现约分以保证运算式中均为真分数。

  • 算法详解

  1. 整数计算

    arith、sum分别用于保存运算后的式子和结果,fh、fh1分别为前后两次运算的运算符,x、y为0-100内的随机整数。

    在进行运算时,并根据运算符号的情况对sum进行相应的计算,并将arith更新。当运算符为减法时,若sum<0需重新生成随机数。当运算符为乘法时,需判断前后两个运算符的优先级,若前一个运算符为加或减,则arith="("+arith+")"+operate[fh1]+y1;。当运算符为除法时,先判断除数是否为0和是否有余数,若是重新生成随机数;之后再判断前后两个运算符的优先级。每步计算完成后fh=fh1来更新运算符。

    2.真分数计算

    首先,随机生成两个分数判断其分子分母的大小(若分子大于等于分母需重新生成分母)并调用yuefen()对真分数进行化简得到真分数。其次,计算这两个分数,若相加通分后需先判断新分子和新分母大小,再约分;若相减通分后需先判断新分子、新分母大小及新分子是否小于0,再约分。记录新分数的值和运算式。最后再生成一分数与上步得到的新分数进行计算,重复上述步骤。

  • 测试运行

2018103002-小学四则运算练习软件项目报告

程序要求输入参数n的数值为0-1000之间。

输入1050,由于n的数值超过其范围,则输出“输入失败,请输入正整数!”

输入150,会生成150道运算式并将其打印输出在result.txt中

2018103002-小学四则运算练习软件项目报告

  • 代码

实现整数计算部分代码

	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

2018103002-小学四则运算练习软件项目报告