四则运算
这个作业属于哪个课程 | 软件工程 |
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 四则运算生成 |
组员 | 学号 |
杜聪 | 3119009428 |
郭泳嘉 | 3119009430 |
Github链接:3119009430/sizeyunsuan at main · guoyongjia/3119009430 (github.com)
题目说明:
自然数:0, 1, 2, …。
- 真分数:1/2, 1/3, 2/3, 1/4, 1’1/2, …。
- 运算符:+, −, ×, ÷。
- 括号:(, )。
- 等号:=。
- 分隔符:空格(用于四则运算符和等号前后)。
- 算术表达式:
e = n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e),
其中e, e1和e2为表达式,n为自然数或真分数。
- 四则运算题目:e = ,其中e为算术表达式。
需求:
- 使用 -n 参数控制生成题目的个数,例如
Myapp.exe -n 10
将生成10个题目。
- 使用 -r 参数控制题目中数值(自然数、真分数和真分数分母)的范围,例如
Myapp.exe -r 10
将生成10以内(不包括10)的四则运算题目。该参数可以设置为1或其他自然数。该参数必须给定,否则程序报错并给出帮助信息。
- 生成的题目中计算过程不能产生负数,也就是说算术表达式中如果存在形如e1− e2的子表达式,那么e1≥ e2。
- 生成的题目中如果存在形如e1÷ e2的子表达式,那么其结果应是真分数。
- 每道题目中出现的运算符个数不超过3个。
- 程序一次运行生成的题目不能重复,即任何两道题目不能通过有限次交换+和×左右的算术表达式变换为同一道题目。例如,23 + 45 = 和45 + 23 = 是重复的题目,6 × 8 = 和8 × 6 = 也是重复的题目。3+(2+1)和1+2+3这两个题目是重复的,由于+是左结合的,1+2+3等价于(1+2)+3,也就是3+(1+2),也就是3+(2+1)。但是1+2+3和3+2+1是不重复的两道题,因为1+2+3等价于(1+2)+3,而3+2+1等价于(3+2)+1,它们之间不能通过有限次交换变成同一个题目。
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 110 | 160 |
· Estimate | · 估计这个任务需要多少时间 | 20 | 30 |
· Analysis | · 需求分析 (包括学习新技术) | 30 | 30 |
· Design Spec | · 生成设计文档 | 10 | 10 |
· Design Review | · 设计复审 (和同事审核设计文档) | 40 | 50 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 90 | 60 |
· Design | · 具体设计 | 100 | 160 |
· Coding | · 具体编码 | 300 | 310 |
· Code Review | · 代码复审 | 40 | 50 |
· Test | · 测试(自我测试,修改代码,提交修改) | 100 | 110 |
Reporting | 报告 | 110 | 110 |
· Test Report | · 测试报告 | 10 | 10 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 50 | 70 |
合计 | 1030 | 1280 |
设计思路:
部分代码:
char getSignal()//运算符
{
char signal[4]={'+','-','x','/'};
return signal[rand()%4];
}
int random(int a)//随机数
{
int b;
b=rand()%a+1;
return b;
}
int gcd(int x,int y)//辗转相除法
{
if(y==0) return x;
return gcd(y,x%y);
}
int answers(int y,int num,int num1,int num2,int num3,int num4,char signal1,char signal2,char signal3,int r)//生成答案
{
int question(int y,int r);
int ans,a,c=0;
FILE *fp;
fp=fopen("Answers.txt","a");
if(num==1)
{
int ans1,ans2;
switch(signal1)
{
case '+':
ans=num1+num2;
fprintf(fp,"题目%d:%d %c %d = %d\n",y,num1,signal1,num2,ans);
fclose(fp);break;
case '-':
if(num1<num2)question(y,r);
else
{
ans=num1-num2;
fprintf(fp,"题目%d:%d %c %d = %d\n",y,num1,signal1,num2,ans);
fclose(fp);break;
}
case 'x':
ans=num1*num2;
fprintf(fp,"题目%d:%d %c %d = %d\n",y,num1,signal1,num2,ans);
fclose(fp);break;
case '/':
a=gcd(num1,num2);
ans1=num1/a;
ans2=num2/a;
c=0;
while(ans1>ans2)
{
ans1=ans1-ans2;
c++;
}
if(c>0)fprintf(fp,"题目%d:%d %c %d = %d'%d/%d\n",y,num1,signal1,num2,c,num1,num2);
if(c=0)fprintf(fp,"题目%d:%d %c %d = %d/%d\n",y,num1,signal1,num2,num1,num2);
fclose(fp);break;
}
}
if(num==2)
{
if(signal2=='x'&&signal1!='/')
{
int ans1;
ans1=num2*num3;
switch(signal1)
{
case '+':
ans=num1+ans1;
fprintf(fp,"题目%d:%d %c %d %c %d = %d\n",y,num1,signal1,num2,signal2,num3,ans);
结果: