软件工程第一周作业----小学生四则运算题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件工程第一周作业----小学生四则运算题相关的知识,希望对你有一定的参考价值。
程序的实现思路:
1、产生随机的数字和运算符,这是组成题目的零件。
数字分为整数和真分数。需要注意的是,为了保证正确,真分数应该要检查(1)分母不为0,(2)不能约分;同时为了避免计算结果是NaN或∞的情况,出于程序简单考虑,生成的整数都是正数。
运算符是简单的四则运算。
2、调用1中的功能,生成题目并计算结果。
在这里控制参与运算的数的个数是随机的、某个位置生成整数还是分数也是随机的。生成题目只需要简单的循环调用就可以了。
计算题目结果使用转化为运算符前缀式的方法。因为开始写的时候没有考虑加括号,直接用函数返回值压栈计算,再在这个基础上加括号就不方便了。这里也可以看见,一个函数最好只实现一个功能。
3、输入输出部分。
首先在屏幕打印一个简单的界面,然后循环地输出题目、输入结果、判断正误,最后给出统计结果。
以下是代码和结果:
#include <stdio.h> #include <stdlib.h> #include <limits.h> #include <time.h> #define limit 30 //分母的范围 int n; //运算数的范围 int FindCommonFactor(int p,int q) {//返回最大公因数,默认2<=p<q; int i; //cursor int commonfactor=1; //common factor for(i=2;i<=p;i++) { if(p%i==0 && q%i==0) { commonfactor*=i; p/=i; q/=i; i=2; } } return commonfactor; } float ProperFraction(char *s,int *i) {//生成真分数存入s中,返回生成的数 int p=0; //分子 int q=0; //分母 int cf; //common fraction while(q==0 || q==1) //生成分母,分母不能是0或1 q=rand()%limit; while(p==0) //生成分子,分子<分母且p!=0 p=rand()%q; if(p>1) //格式化分数 { cf=FindCommonFactor(p,q); p/=cf; q/=cf; } s[*i]=‘(‘; //存入字符串 (*i)++; if(p<10) { s[*i]=p+‘0‘; (*i)++; } else { s[*i]=p/10+‘0‘; (*i)++; s[*i]=p-(s[*i-1]-‘0‘)*10+‘0‘; (*i)++; } s[*i]=‘/‘; (*i)++; if(q<10) { s[*i]=q+‘0‘; (*i)++; } else { s[*i]=q/10+‘0‘; (*i)++; s[*i]=q-(s[*i-1]-‘0‘)*10+‘0‘; (*i)++; } s[*i]=‘)‘; (*i)++; return (float)p/(float)q; } int Operator(char *s,int *i) {//随机生成运算符,存入字符串,返回运算符编号 int o=rand()%4; if(o==0) s[*i]=‘+‘; if(o==2) s[*i]=‘-‘; if(o==1) s[*i]=‘*‘; if(o==3) s[*i]=‘/‘; (*i)++; return o%2+1; } int Decimal(char *s,int* i) {//随机生成整数,存入字符串,返回这个整数 int num=0; //生成数 int tmp[10]={0}; //暂存数组 int j=0; //cursor int substitude=0; //替身 while(num==0) num=rand()%n; substitude=num; while(num>0) //反序按位拆开 { tmp[j]=num%10; num/=10; j++; } for(j--;j>=0;j--) //存入字符串 { s[*i]=tmp[j]+‘0‘; (*i)++; } return substitude; } int Rank(char x,char y){ //x>y return1; x<=y return0; if(x==‘+‘ || x==‘-‘) x=1; if(x==‘*‘ || x==‘/‘) x=2; if(x==‘#‘) x=0; if(y==‘+‘ || y==‘-‘) y=1; if(y==‘*‘ || y==‘/‘) y=2; if(y==‘#‘) y=0; return (int)x>=(int)y; } float Question(char *s) {//生成混合运算的字符串,返回计算结果 int i=0; //cursor int j=0; //cursor int DorF; //Decimal or Fraction int len=0; //参与运算数的数量 char stack[11]="#"; //符号栈,栈底压入最低级的符号 float result[10]={0}; //结果栈 int stacktop=1; //符号栈顶 int resulttop=0; //结果栈顶 float newnum=0; //新生成数 while(len<2) //参与运算的数至少有2个 len=rand()%11; for(j=0;j<len-1;j++) { DorF=rand()%2; //随机生成数 if(DorF) newnum=(float)Decimal(s,&i); else newnum=ProperFraction(s,&i); result[resulttop]=newnum; //新数入栈 resulttop++; Operator(s,&i); //生成运算符 while(Rank(stack[stacktop-1],s[i-1])) //弹出运算符并计算 { switch((int)stack[stacktop-1]) //计算 { case ‘+‘:result[resulttop-2]+=result[resulttop-1];break; case ‘-‘:result[resulttop-2]-=result[resulttop-1];break; case ‘*‘:result[resulttop-2]*=result[resulttop-1];break; case ‘/‘:result[resulttop-2]/=result[resulttop-1];break; } resulttop--; //修正结果栈 stacktop--; //弹出运算符 } stack[stacktop]=s[i-1]; //新运算符入栈 stacktop++; } DorF=rand()%2; if(DorF) newnum=(float)Decimal(s,&i); else newnum=ProperFraction(s,&i); result[resulttop]=newnum; //新数入栈 resulttop++; while(stacktop>1) //剩下的计算 { switch((int)stack[stacktop-1]) //计算 { case ‘+‘:result[resulttop-2]+=result[resulttop-1];break; case ‘-‘:result[resulttop-2]-=result[resulttop-1];break; case ‘*‘:result[resulttop-2]*=result[resulttop-1];break; case ‘/‘:result[resulttop-2]/=result[resulttop-1];break; } resulttop--; //修正结果栈 stacktop--; //弹出运算符 } s[i]=0; //题目结束 return result[0]; } float Trans(char *input){ int i=0; //cursor int p=0; //分子 int q=0; //分母 float num=0; //数值 int neg=0; //负数 if(input[0]==‘-‘) { neg=1; i++; } while(input[i]!=0 && input[i]!=‘/‘) { p*=10; p+=input[i]-‘0‘; i++; } if(input[i]==0) num=(float)p; else { i++; while(input[i]!=0) { q*=10; q+=input[i]-‘0‘; i++; } if(q<=0) num=0.0/0.0; else { if(p!=1 && FindCommonFactor(p,q)!=1) num=0.0/0.0; else num=(float)p/(float)q; } } return num; } int main(void) { int i=0;//cursor int questionnum=0; //题目数量 char question[100]={0}; //题目 float result=0.0; //题目结果 char input[50]={0}; //输入结果 int statistic=0; //统计正确量 float inputnum=0; //输入数值 for(;i<80;i++) //界面 printf("*"); printf("\\n欢迎使用算式生成器!\\n"); printf("\\n请输入要求:\\n"); printf("参与计算数的范围:"); scanf("%d",&n); printf("生成算式的数量:"); scanf("%d",&questionnum); printf("\\n"); for(i=0;i<questionnum;i++) //生成题目并判断输入是否正确 { srand (time(NULL)); result=Question(question); printf("%s = ",question); scanf("%s",input); inputnum=Trans(input); if(abs(inputnum-result)<=0.000005) { printf("correct!\\n\\n"); statistic++; } else printf("error!\\n\\n"); } printf("correct entry: %d\\n",statistic); //统计结果 printf("accuracy: %.2f%%\\n",((float)statistic*100)/questionnum); return 0; }
以上是关于软件工程第一周作业----小学生四则运算题的主要内容,如果未能解决你的问题,请参考以下文章