四则运算随机生成器-----部分代码详解与全部代码地址

本文介绍了一个Java程序,用于根据小学生数学概念生成不含负数和小数的四则运算练习题。程序可接受输入参数n,生成n道练习题,并支持括号及真分数运算。文章详细解析了代码实现,包括避免负数和小数、随机括号生成、无意义括号删除等功能。作者分享了项目经验,强调了灵活运用库函数和借鉴他人代码的重要性,并提供了完整代码的GitHub链接。

题目要求

软件基本功能要求如下:
1.程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号±*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。
2.每个练习题至少要包含2种运算符。同时,由于小学生没有分数与负数的概念,你所出的练习题在运算过程中不得出现负数与非整数,比如不能出现 3÷5+2=2.6,2-5+10=7等算式
3.练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。
4.当程序接收的参数为4时,以下为一个输出文件示例。
2018010203
13+17-1=29
11*15-5=160
3+10+4-16=1
15÷5+3-2=4
软件附加功能要求如下:(请有余力的同学完成)
1.支持有括号的运算式,包括出题与求解正确答案。注意,算式中存在的括号数必须大于2对,且不得超过运算符的个数。
2.扩展程序功能支持真分数的出题与运算(只需要涵盖加减法即可),例如:1/6 + 1/8 + 2/3= 23/24。注意在实现本功能时,需支持运算时分数的自动化简,比如 1/2+1/6=2/3,而非4/6,且计算过程中与结果都须为真分数。

代码地址:见文章底部

项目预期时间与实际时间

psp2.1任务内容计划共完成需要的时间(h)实际完成需要的时间(h)
Planning计划0.10.1
Esimate估计这个任务需要多少时间5024
Developement开发4822.5
Analysis需求分析(包括学习新技术)22
Design Spec生成设计文档11
Coding Standard代码规范10.5
Design具体设计21
Coding具体编码2015
Coding review代码复审11
Test测试12
Reporting报告31.5
Test Report测试报告00
Size Measurement计算工作量0.50.5
Postmortem & Process Improvement Plan事后总结, 并提出过程改进计划11

部分代码详解

基本功能

生成四则运算表达式
	int num = sc.nextInt();
	boolean judge=judge(num);
	Random random=new Random();
	int realnum=num-random.nextInt(num);
	char[] operator=new char[]{'+','-','*','/'};
	//判断参数合法性。整数
	if(judge){			
		//编写加减乘除运算
		for(int i=0;i<num-realnum;i++){
			int n=random.nextInt(3)+3; //3-5个运算符
			
			int[] number=new int[n+1]; 
			String ex=new String();
			int numcount[]=new int [n+1];
			for(int o=0;o<n+1;o++) {
				numcount[o]=0;
			}
			for(int j=0;j<=n;j++){
				number[j]=random.nextInt(100)+1; 
			}//4-5个数字
			
			
			for(int o=0;o<=n;o++) {
				int temp=number[o];

				while(temp!=0) {
					numcount[o]++;
					temp/=10;
				}
			//确定生成的每个随机数的位数				
			for(int j=0;j<n;j++){
				int s=random.nextInt(4);//随机选择某个运算符
				if(s==1) {
					number[j]=decide1(number[j],number[j+1]);
					int temp=number[j];
					numcount[j]=0;
					while(temp!=0) {
						numcount[j]++;
						temp/=10;
					}
				}
				if(s==3){
					number[j+1]=decide3(number[j],number[j+1]);
					int temp=number[j+1];
					numcount[j+1]=0;
					while(temp!=0) {
						numcount[j+1]++;
						temp/=10;
					}
				}
				ex+=String.valueOf(number[j]);
				ex+=String.valueOf(operator[s]);///5+4+6+9
			}
			ex+=String.valueOf(number[n]);
避免结果出现负数与小数
				try {
					String a ="";
					a=a+jse.eval(ex);
					int b = Integer.valueOf(a);
					if( b<0) {
						i=i-1;
				}
				else{
					expression1.add(ex);
				}
				}
				catch (NumberFormatException e) {
						// TODO Auto-generated catch block
						i=i-1;
						
				}

附加功能

随机生成括号
			int m=random.nextInt(n-1)+2;
			int num0=0;
		    while(num0==0){
				for(int k=0;k<m;k++) {	
					int insertPos1=random.nextInt(n)*2;				
					int insertPos2=n*2+1-random.nextInt(n-insertPos1/2)*2;
					int  rePos1=insertPos1-insertPos1/2;
					int rePos2=insertPos2-insertPos2/2;	
					for(int w=0;w<rePos1;w++) {
						insertPos1+=(numcount[w]-1);

					}
					numcount[rePos1]++;
					for(int w=0;w<rePos2;w++) {
						insertPos2+=(numcount[w]-1);

					}
					numcount[rePos2-1]++;

					StringBuilder ex0 = new StringBuilder(ex);
					ex0.insert(insertPos1, "(");

					ex0.insert(insertPos2, ")");
					ex=ex0.toString();
					
				}
删除包裹一个数字的无意义括号
				ArrayList<String> numbers=new ArrayList<String>();
				for(int b=0;b<=n;b++) {
					String number0='('+String.valueOf(number[b])+')';
					numbers.add(number0);
				}
				num0=0;
				for(String number0:numbers) {
					ex=ex.replace(number0, String.valueOf(number[num0]));
					num0++;
				}
真分数加减运算
for(int i=0;i<realnum;i++) {
		int n=random.nextInt(3)+3;//3-5个运算符

		int[] number=new int[(n+1)*2];
		int result1 = 0,result2=0;//result1为最终结果的分子,result2为最终结果的分母
		for(int j=0;j<(n+1)*2;j++){
			number[j]=random.nextInt(10)+1; 
		}//4-5个数字
		for(int k=0;k<(n+1)*2;k+=2) {
			if(number[k]>number[k+1]) {
				int temp=number[k];
				number[k]=number[k+1];
				number[k+1]=temp;
			}
		}
		result1=number[0];
		result2=number[1];
		boolean flag=false;
		boolean flag2=false;
		for(int k=0;k<=n-1;k++) {
		    result1=number[(k+1)*2]*result2+number[(k+1)*2+1]*result1;
			result2=result2*number[(k+1)*2+1];
			int result0=division(result1,result2);
			result1/=result0;
			result2/=result0;
			if(k==n-1&&result1>result2) {
				flag=true;//结果不能为假分数,否则重新生成
			}
			else if(k==n-1&&result1==result2) {
				flag2=true;//结果为1,直接生成1,而不是1/1
			}
		}
		if(flag) {
			i--;
			continue;
		}
		String ex = new String();
		for(int k=0;k<n;k++) {
			ex+=String.valueOf(number[k*2])+'/'+String.valueOf(number[k*2+1])+'+';
		}
		ex+=String.valueOf(number[n*2])+'/'+String.valueOf(number[n*2+1]);
		if(!flag2) {
		ex+='='+String.valueOf(result1)+'/'+String.valueOf(result2);
		}else {
			ex+='='+'1';
		}
		
		expression2.add(ex);
	}

总结

/ 此次作业还是花了很多时间,其中个人认为最难的点在于生成括号,如何判断生成右括号还是左括号还是不生成括号。真分数相对就简单些,用正常的两两运算,循环下来得出最后的结果。自己写下来,发现如果能提前熟知java库里的多种函数运用,那么工作量将大大减少许多,包括本次项目也是用了javascript里的
eval函数,免去了计算的代码量。另外String类里的一些函数也帮我免去了很多工作。让我深切的感知到学会灵活运用java自带的函数可以减少许多工作。
/ 除此之外,在写代码前,也可以去网上参考他人的代码,借用前人的经验,使得自己用更少的时间做更多的事情,也能学到其他人的智慧,对比自己的想法,从而收获更多。

github地址:https://github.com/lost1deer/javaWork.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值