四则运算
1.作业规范要求
| 博客編輯 | https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18 |
|---|---|
| 作业要求 | https://edu.cnblogs.com/campus/ahgc/AHPU-se-JSJ18/homework/11377 |
| 作业目标 | 写一个能自动生成小学四则运算题目的程序,然后在此基础上扩展: |
| 1)除了整数以外,还要支持真分数的四则运算,例如:1/6+1/8=7/24 | |
| 2)程序要求能处理用户的输入,判断对错,累积分数 | |
| 3)程序支持可以由用户自行选择加、减、乘、除运算 | |
| 4)使用-n参数控制生成题目的个数,例如Myapp.exe -n 10,将生成10个题目 | |
| 学号 | 3180701234 |
2.题目要求
写一个能自动生成小学四则运算题目的程序,然后在此基础上扩展:
1)除了整数以外,还要支持真分数的四则运算,例如:1/6+1/8=7/24
2)程序要求能处理用户的输入,判断对错,累积分数
3)程序支持可以由用户自行选择加、减、乘、除运算
4)使用-n参数控制生成题目的个数,例如Myapp.exe -n 10,将生成10个题目
3.代码提交
1.中缀转后缀并计算
void qiuzhi(char *bds)//中转后并求值
{ FILE *fp;
int i = 0;
stack *ysf = (stack*)malloc(sizeof(stack));//为表达式开辟一个stack
ysf->size = 0;
float num[50];//用于求值的数组
int numpos = 0;//用于求值的数组位置,因使用较少为提高效率选择数组
printf("后缀表达式为:");//附加
while (bds[i] != '=')
{
if (bds[i] == '\0')
{
printf("表达式应该有=");
return;
}
if (bds[i] <= '9'&&bds[i] >= '0')//转化数字
{
num[++numpos] = 0;
while (bds[i] <= '9'&&bds[i] >= '0')
{
num[numpos] *= 10;
num[numpos] += (bds[i] - '0');
++i;
}
if (bds[i] == '.')
{
double f_car = 0.1;//定义基数
++i;
while (bds[i] <= '9'&&bds[i] >= '0')
{
num[numpos] += ((bds[i] - '0')*f_car);
f_car *= 0.1;
++i;
}
}//计算小数点
}
else
{
if (empty(ysf))
push(ysf, bds[i]);
else
{
if (bds[i] == '(')
push(ysf, bds[i]);
else if (bds[i] == ')')
{
while (top(ysf) != '(')
{
reckon(&num[numpos - 1], num[numpos], top(ysf));
printf("%c", pop(ysf));
--numpos;
}
pop(ysf);//弹出右括号
}
else
{
while (compare(bds[i])<=compare(top(ysf)))
{
reckon(&num[numpos - 1], num[numpos], top(ysf));
printf("%c", pop(ysf));
--numpos;
}
push(ysf, bds[i]);
}
}
++i;
}
}
while (!empty(ysf))
{
reckon(&num[numpos - 1], num[numpos], top(ysf));
printf("%c", pop(ysf));
--numpos;
}
fopen("/练习程序/answer.txt","w+");
printf("\n运算结果为:%.2f\n", num[1]);
fprintf(fp,"%.2f\n",num[1]);
}
void reckon(float *a, float b, char c)//用于将两数字合并,前数传地址
{ //表达式运算定义
int t;
if (c == '-')
{ if(*a<b)//非负
{ t=*a;*a=b;b=t;}
(*a)-=b;
}
else if (c == '+')
{
(*a) += b;
}
else if (c == '*')
{
(*a) *= b;
}
else
if(b!=0)
(*a) /= b;
}
2.分数运算
void qiuzhi1(int a,int b,int c,int d,char s)
{ int x,y,t,m;
float p,q;//中间数
int re1,re2,u;//分子分母
x=getGcd(a,b);//对a,b约分
a/=x;
b/=x;
y=getGcd(c,d);//对c,d约分
c/=y;
d/=y;
FILE *fp=fopen("/练习程序/subject.txt","w+");//读写文件位置
switch(s)//选取运算符
{
case '+':
re1=a*d+c*b;
re2=b*d;
t=getGcd(re1,re2);
re1/=t;
re2/=t;
printf("%d/%d + %d/%d=%d/%d\n",a,b,c,d,re1,re2);
fprintf(fp, "%d/%d + %d/%d=%d/%d\n",a,b,c,d,re1,re2);
break;
case '-':
p=a/b;
q=c/d;
if(p<q)//判断结果不为负
{
u=a;
a=c;
c=u;
u=b;
b=d;
d=u;
}
re1=a*d-c*b;//结果分子的运算
re2=b*d;
t=getGcd(re1,re2);//约分
re1/=t;
re2/=t;
printf("%d/%d - %d/%d=%d/%d\n",a,b,c,d,re1,re2);
fprintf(fp, "%d/%d - %d/%d=%d/%d\n",a,b,c,d,re1,re2);
break;
case '*':
re1=a*c;
re2=b*d;
t=getGcd(re1,re2);
re1/=t;
re2/=t;
if(a==0||c==0)//有分数为0时
{
printf("%d/%d * %d/%d=0",a,b,c,d);
fprintf(fp, "%d/%d * %d/%d=0",a,b,c,d);
}
else
printf("%d/%d * %d/%d=%d/%d\n",a,b,c,d,re1,re2);
fprintf(fp, "%d/%d * %d/%d=%d/%d\n",a,b,c,d,re1,re2);
break;
case '/':
re1=a*d;
re2=b*c;
t=getGcd(re1,re2);
re1/=t;
re2/=t;
if(a==0)
{printf("%d/%d / %d/%d=0",a,b,c,d);//结果为0
fprintf(fp, "%d/%d / %d/%d=0",a,b,c,d);
}
else{
printf("%d/%d / %d/%d=%d/%d\n",a,b,c,d,re1,re2);
fprintf(fp, "%d/%d / %d/%d=%d/%d\n",a,b,c,d,re1,re2);
}
}
}
3.读取题目信息
void creat1(int num,int r)
{
char a[]={'+','-','*','/'};
int X,c,t;
int i,j,b,count;
int x,y,x1,y1,z,e;
int n=sizeof(a);
srand(time(NULL));
FILE *fp = NULL;//打开文件
fp = fopen("/练习程序/test.txt", "w+");
for(j=0;j<num;j++)
{ x=rand()%r;
y=rand()%r;
x1=rand()%r;
y1=rand()%r;
z=rand()%r;
X=rand()%4;
i=rand()%n;
b=rand()%n;
c=rand()%n;
x!=y;
switch(X)//控制符号数
{ case 0:
printf("第%d题:%d%c%d= \n",j+1,x,a[i],y);
fprintf(fp, "%d%c%d= \n",x,a[i],y);
break;
case 1:
printf("第%d题:%d%c%d%c%d= \n",j+1,x,a[i],y,a[b],z);
fprintf(fp, "%d%c%d%c%d= \n",x,a[i],y,a[b],z);
break;
case 2:
fprintf(fp, "%d%c%d%c%d%c%d= \n",x,a[i],y,a[b],x1,a[c],z);
printf("第%d题:%d%c%d%c%d%c%d= \n",j+1,x,a[i],y,a[b],x1,a[c],z);
break;
}
}
fclose(fp);
}
void save()
{ stack *p;
char bds[50];
FILE *fx;//读取文件
int line,i;
if((fx = fopen("/练习程序/test.txt","r")) == NULL)
{
printf("error\n");
exit (1) ;
}
char buf[1024];
for (i = 0; i < 1024; i++)
{ while(fgets(bds,50,fx) != NULL)//输出文件
{
line = strlen(bds);
bds[line-1] = '\0'; /*去掉换行符*/
printf("%s \n",bds);
qiuzhi(bds);
}
fclose (fx);
}
}
4.主函数
int main()
{
int num1,num2,m,n,r,type;
printf("请选择输出类型:1or2");
scanf("%d\n",&type);
if(type==1)
{ printf("请输入生成题目数量: ");
scanf("%d \n",&num1);
printf("请输入分子分母取值范围: ");
scanf("%d %d",&m,&n);
creat2(num,m,n);
}
else if(type==2)
{
printf("请输入生成题目数量: ");
scanf("%d \n",&num2);
printf("请输入取值范围: ");
scanf("%d %d",&r);
creat1(num,r);
save();//输出答案
}
return 0;
}
4.测试结果
1.分数运算


2.文件生成

5.PSP表格
| psp2.1 | 任务内容 | 计划完成需要的时间(min) | 实际完成需要的时间(min) |
|---|---|---|---|
| Planning | 计划 | 100 | 240 |
| Estimate | 估计这个任务需要多少时间,并规划大致工作步骤 | 2000 | 3894 |
| Development | 开发 | 200 | 366 |
| Analysis | 需求分析(包括学习新技术) | 180 | 1400 |
| Design Spec | 生成设计文档 | 100 | 150 |
| Design Review | 设计复审 | 60 | 120 |
| Coding Standard | 代码规范 | 60 | 70 |
| Design | 具体设计 | 20 | 35 |
| Coding | 具体编码 | 360 | 540 |
| Code Review | 代码复审 | 60 | 164 |
| Test | 测试(自我测试,修改代码,提交修改) | 120 | 180 |
| Reporting | 报告 | 60 | 80 |
| Test Report | 测试报告 | 20 | 30 |
| Size Measurement | 计算工作量 | 10 | 30 |
| Postmortem & Process Improvement Plan | 事后总结,并提出过程改进计划 | 40 | 60 |
| 合计 | 2290 | 4408 |
6.个人总结
从刚开始看到题目之后觉得只是很简单的题目很好写,并没有太大关注,等到自己实际操作时却感到不容易,学c语言学的最多也最熟悉就使用了c语言,在判断运算符优先级时,意识到要运用数据结构的内容时,又抽出了时间去复习。另外就是代码功能的实现问题,由于其中很多地方出现了一些问题,函数的参数不一,造成了很大的困扰,其次就是规范化,使得代码本身浪费了很多的时间,都是需要注意的地方,代码本身的函数与参数要规范好才能提高效率,这次的题目让我学到了很多东西,收获颇多
浙公网安备 33010602011771号