题目要求
软件基本功能要求如下:
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.1 | 0.1 |
| Esimate | 估计这个任务需要多少时间 | 50 | 24 |
| Developement | 开发 | 48 | 22.5 |
| Analysis | 需求分析(包括学习新技术) | 2 | 2 |
| Design Spec | 生成设计文档 | 1 | 1 |
| Coding Standard | 代码规范 | 1 | 0.5 |
| Design | 具体设计 | 2 | 1 |
| Coding | 具体编码 | 20 | 15 |
| Coding review | 代码复审 | 1 | 1 |
| Test | 测试 | 1 | 2 |
| Reporting | 报告 | 3 | 1.5 |
| Test Report | 测试报告 | 0 | 0 |
| Size Measurement | 计算工作量 | 0.5 | 0.5 |
| Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 1 | 1 |
部分代码详解
基本功能
生成四则运算表达式
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自带的函数可以减少许多工作。
/ 除此之外,在写代码前,也可以去网上参考他人的代码,借用前人的经验,使得自己用更少的时间做更多的事情,也能学到其他人的智慧,对比自己的想法,从而收获更多。
本文介绍了一个Java程序,用于根据小学生数学概念生成不含负数和小数的四则运算练习题。程序可接受输入参数n,生成n道练习题,并支持括号及真分数运算。文章详细解析了代码实现,包括避免负数和小数、随机括号生成、无意义括号删除等功能。作者分享了项目经验,强调了灵活运用库函数和借鉴他人代码的重要性,并提供了完整代码的GitHub链接。

被折叠的 条评论
为什么被折叠?



